【发布时间】:2021-09-13 10:12:21
【问题描述】:
我目前正在使用attrs 设计一个类结构。这是一个树状结构,我需要一个父反向链接用于某些目的。 OTOH,我想使用冻结类(有缓存的属性,它们依赖于只读状态)。
这意味着树必须自下而上实例化,子在父之前。为了解决这个问题,我发明了一种特殊的 weakref 对象,它可以被惰性绑定一次。
class LateRef(Generic[T]):
def __init__(self):
self.ref: Optional[T] = None
def set(self, obj: T):
if self.ref is not None:
raise RuntimeError('Reference can only be set once.')
self.ref = weakref.ref(obj)
def __call__(self) -> Optional[T]:
if self.ref is None:
return None
return self.ref()
有自定义初始化代码在child中创建一个未绑定的引用,并在parent中绑定它们:
@attr.s(auto_attribs=True, frozen=True)
class Child:
some_attribute:str = "whatever"
def __attrs_post_init__(self):
self.__dict__['parent'] = LateRef()
@attr.s(auto_attribs=True, frozen=True)
class Parent:
children: List[Child] = attr.ib(converter=_deepclone) # off-screen :-)
def __attrs_post_init__(self):
for child in self.children:
child.parent.set(self)
由于child的冻结,我需要通过后门潜入Child.parent属性。以前我把它作为自定义工厂的类属性,但后来它变成了attrs-attribute,它真的不应该是。例如。我不希望parent 出现在散列、比较、str 表示等方面。
代码已经可以工作了,但是:如您所见,我希望做正确的事情并尽可能地进行类型注释。将parent 直接放在__dict__ 中意味着通常的工具不知道预期的类型。事实上,他们甚至可能会抱怨 parent 属性根本不存在。
长话短说:有没有办法用类型注释将parent 声明为类属性,同时告诉attr.s 跳过/忽略它?还是有其他我忽略的解决方案?
编辑:即如何让静态类型检查器识别parent 属性的类型,而不是使其成为attr.ib。
【问题讨论】:
标签: python python-typing python-attrs