Python attr模块中attr.ib()与普通实例变量的功能差异疑问
用
attr.ib()定义 vs 方法内赋值的差异 核心功能区别
attr.ib()是类的声明式字段:- 会被attr库识别,自动生成
__init__方法的参数,实例化时可直接传入值初始化。 - 自动参与生成
__repr__(打印实例时显示该字段)、__eq__(实例比较时包含该字段)等方法。 - 支持默认值、验证器、转换器等attr特性,比如
attr.ib(default=0, validator=instance_of(int))。 - 属于类的"正式"成员,用
attr.asdict()可直接导出该字段。
- 会被attr库识别,自动生成
方法内
self.third_member_var = xxx是动态赋值:- 不属于类声明的一部分,实例化时不会自动初始化,只有调用对应方法
func()后才会存在。 - 默认不会出现在
__repr__或__eq__逻辑里,除非手动修改这些方法。 - 没有attr提供的验证、转换特性,完全由代码逻辑控制赋值时机和值。
- 属于实例的动态属性,方法未执行时访问会报错。
- 不属于类声明的一部分,实例化时不会自动初始化,只有调用对应方法
是遗漏还是有意为之?
大概率是有意为之,而非遗漏,适用场景不同:
- 如果属性是类实例的核心状态,需要初始化时确定,或者依赖attr的自动特性(验证、默认值等),就会用
attr.ib()。 - 如果属性是临时状态、需要特定逻辑计算后生成,或者仅在特定场景下才需要存在,就会选择在方法内动态赋值。
举个实际例子:
import attr @attr.s class MyClass: first_member_var = attr.ib(default=1) # 核心属性,初始化即存在 second_member_var = attr.ib(validator=attr.validators.instance_of(str)) # 带验证的核心属性 def func(self, input_val): # 经计算生成的属性,仅调用func后存在 self.third_member_var = input_val * 2
- 实例化
MyClass(10, "test")时,first_member_var和second_member_var已存在,third_member_var不存在。 - 调用
obj.func(5)后,obj.third_member_var才会被赋值为10。 - 打印
obj时,默认只会显示前两个字段。
若为遗漏,开发者通常会把third_member_var也用attr.ib()定义,哪怕设置默认值None。
内容的提问来源于stack exchange,提问作者24n8
相关产品推荐
相关产品推荐

