如何在 python 中构建冻结 class 的循环引用实例
How to construct circular referencing instances of a frozen class in python
我有一个相互引用的数据class实例。
from dataclasses import dataclass
@dataclass()
class Foo:
id: int
neighbor: 'Foo'
foo = Foo(1, None)
bar = Foo(2, foo)
foo.neighbor = bar
我真的想要一个冻结的 class,因为不能在多线程中操作这些对象 运行。但是如果我声明 frozen=True
,最后一行显然会引发错误。我想不出如何处理这个问题。我阅读了 但解决方案对我不起作用,因为 foo.neighbor
应该指向另一个冻结的实例。
有什么办法可以实现吗?我不受 dataclasses 的约束。但是我在使用 namedtuples 时遇到了同样的问题。
frozen
通过覆盖 __setattr__
来工作。您可以通过直接访问实例的 __dict__
属性来完全绕过 __setattr__
。
foo.__dict__['neighbor'] = bar
我不知道这是否会产生任何意想不到的副作用(如果您使用 __slots__
来防止创建 __dict__
肯定不会起作用),但它可能足以满足您的用例。
(如果实现更改为使用 C 扩展而不是当前动态生成源代码以传递给 exec
的方法,这在 dataclass
的未来版本中也可能会失败。namedtuple
沿着这些路线发展,我相信。)
或者,您可以使用 dataclasses
本身用来初始化冻结 class 属性的相同技巧:显式使用 object.__setattr__
。
object.__setattr__(foo, 'neighbor', bar)
我有一个相互引用的数据class实例。
from dataclasses import dataclass
@dataclass()
class Foo:
id: int
neighbor: 'Foo'
foo = Foo(1, None)
bar = Foo(2, foo)
foo.neighbor = bar
我真的想要一个冻结的 class,因为不能在多线程中操作这些对象 运行。但是如果我声明 frozen=True
,最后一行显然会引发错误。我想不出如何处理这个问题。我阅读了 foo.neighbor
应该指向另一个冻结的实例。
有什么办法可以实现吗?我不受 dataclasses 的约束。但是我在使用 namedtuples 时遇到了同样的问题。
frozen
通过覆盖 __setattr__
来工作。您可以通过直接访问实例的 __dict__
属性来完全绕过 __setattr__
。
foo.__dict__['neighbor'] = bar
我不知道这是否会产生任何意想不到的副作用(如果您使用 __slots__
来防止创建 __dict__
肯定不会起作用),但它可能足以满足您的用例。
(如果实现更改为使用 C 扩展而不是当前动态生成源代码以传递给 exec
的方法,这在 dataclass
的未来版本中也可能会失败。namedtuple
沿着这些路线发展,我相信。)
或者,您可以使用 dataclasses
本身用来初始化冻结 class 属性的相同技巧:显式使用 object.__setattr__
。
object.__setattr__(foo, 'neighbor', bar)