使用attrs库定义类时如何正确初始化依赖其他属性的成员
你写的报错代码本质是在类定义阶段就执行了WebClient的初始化逻辑,此时token还只是attrs的属性定义占位符(也就是你提到的_CountringAttr对象),并非实例化时传入的实际字符串值,自然会出现参数类型错误。
attrs提供了两种成熟的方案实现你要的「实例化时同步初始化依赖对象」的需求:
方案1:使用__attrs_post_init__后置初始化钩子
这是最贴近原生Python__init__写法的方案,attrs会在自动生成的初始化逻辑执行完成后,自动调用这个方法:
import attr # 注意替换为你实际的WebClient导入路径 from xxx import WebClient @attr.s class SomeClass: token: str = attr.ib() # init=False表示该属性不需要外部传入,由类内部自行初始化 client: WebClient = attr.ib(init=False) def __attrs_post_init__(self) -> None: # 执行到这里时self.token已经被赋值为实例化传入的实际字符串 self.client = WebClient(auth=self.token)
方案2:使用带self参数的Factory工厂
如果不想单独写初始化方法,可以用attr.Factory的takes_self参数直接声明依赖当前实例属性的默认值:
import attr from xxx import WebClient @attr.s class SomeClass: token: str = attr.ib() client: WebClient = attr.ib( # takes_self=True会把当前实例作为参数传入工厂函数 default=attr.Factory(lambda self: WebClient(auth=self.token), takes_self=True), init=False )
如果你用的是attrs 20.1.0之后推出的新API@define/field,核心逻辑完全一致,仅装饰器和属性声明的写法略有调整即可。
内容的提问来源于stack exchange,提问作者Prime
相关产品推荐
相关产品推荐

