如何在Python3中定义包含自身列表属性的dataclass
解决Dataclass中定义自身列表类型属性的问题
问题原因
- 未定义的类名称:在类体内部定义类型提示时,
Directory类还未完成定义,直接引用Directory会触发NameError。 - 可变默认值陷阱:dataclass中使用
[]作为默认值会导致所有实例共享同一个列表,这是Python可变默认参数的常见问题。
解决方案
方法1:使用字符串类型提示(Python 3.7+)
将类型提示中的Directory用字符串包裹,Python会延迟解析这个类型:
from dataclasses import dataclass, field from typing import List def generate_randomly(): # 示例随机生成函数 return "random_dir" @dataclass class Directory: name: str = field(default_factory=generate_randomly) num_of_files: int = 0 subdirectories: List["Directory"] = field(default_factory=list)
方法2:导入annotations未来特性(Python 3.7+)
通过from __future__ import annotations让所有类型提示以字符串形式存储,无需手动包裹:
from __future__ import annotations from dataclasses import dataclass, field from typing import List def generate_randomly(): return "random_dir" @dataclass class Directory: name: str = field(default_factory=generate_randomly) num_of_files: int = 0 subdirectories: List[Directory] = field(default_factory=list)
方法3:使用Self类型(Python 3.11+)
Python 3.11引入了Self类型,可以更直观地表示自身类型:
from __future__ import annotations from dataclasses import dataclass, field from typing import List, Self def generate_randomly(): return "random_dir" @dataclass class Directory: name: str = field(default_factory=generate_randomly) num_of_files: int = 0 subdirectories: List[Self] = field(default_factory=list)
验证代码
使用修正后的类创建实例:
dir1 = Directory('folder1') dir2 = Directory('folder2') parent_dir = Directory(subdirectories=[dir1, dir2]) print(parent_dir) # 输出示例:Directory(name='random_dir', num_of_files=0, subdirectories=[Directory(name='folder1', num_of_files=0, subdirectories=[]), Directory(name='folder2', num_of_files=0, subdirectories=[])])
内容的提问来源于stack exchange,提问作者viral_mutant
相关产品推荐
相关产品推荐

