Python:确保 class 属性不在公共继承树之间共享
Python: ensure class attributes are not shared between common inheritance trees
我有种好像在哪里见过的感觉,但我不确定那是重建的记忆还是真的存在。无论如何,我找不到对这种情况的参考:
class A:
a = 1
class B(A): # should have it's own class attribute 'a'
pass
class C(A): # should have it's own class attribute 'a' and newly defined 'c'
c = 3
在上面的例子中,A.a is B.a is C.a
。但是,我实际上希望在保持这种结构的同时将它们分开。这是有充分理由的,我不想讨论实例变量。原因是在我的应用程序中,所有这些 类 都用作 'namespaces'。为了解决 'issue',我将 A
继承的部分替换为自身的副本(伪代码):
class A:
a = 1
class B(A): # B.a resolves to A.a
pass
class C(A): # C.a resolves to A.a
c = 3
copy_func(B.A, A) # investigates public attrs of A and B and create copies, now B.a is not A.a
copy_func(C.A, A) # investigates public attrs of A and B and create copies, now C.a is not A.a
定义 __init_subclass__
以在定义子类时自动复制超类属性。
import copy
class A:
a = []
def __init_subclass__(cls, **kwargs):
for base in cls.mro():
for attr in base.__dict__:
if attr not in cls.__dict__ and not attr.startswith("_"):
setattr(cls, attr, copy.copy(getattr(cls, attr)))
这将从超类命名空间中复制所有不以 _
开头的内容。在实践中,人们可能希望应用更严格的规则。
定义子类时__init_subclass__
自动运行。这意味着子类无需 运行 显式编码即可获得复制的属性。
class B(A):
pass
class C(A):
c = 3
assert B.a is not A.a
assert C.a is not A.a
我有种好像在哪里见过的感觉,但我不确定那是重建的记忆还是真的存在。无论如何,我找不到对这种情况的参考:
class A:
a = 1
class B(A): # should have it's own class attribute 'a'
pass
class C(A): # should have it's own class attribute 'a' and newly defined 'c'
c = 3
在上面的例子中,A.a is B.a is C.a
。但是,我实际上希望在保持这种结构的同时将它们分开。这是有充分理由的,我不想讨论实例变量。原因是在我的应用程序中,所有这些 类 都用作 'namespaces'。为了解决 'issue',我将 A
继承的部分替换为自身的副本(伪代码):
class A:
a = 1
class B(A): # B.a resolves to A.a
pass
class C(A): # C.a resolves to A.a
c = 3
copy_func(B.A, A) # investigates public attrs of A and B and create copies, now B.a is not A.a
copy_func(C.A, A) # investigates public attrs of A and B and create copies, now C.a is not A.a
定义 __init_subclass__
以在定义子类时自动复制超类属性。
import copy
class A:
a = []
def __init_subclass__(cls, **kwargs):
for base in cls.mro():
for attr in base.__dict__:
if attr not in cls.__dict__ and not attr.startswith("_"):
setattr(cls, attr, copy.copy(getattr(cls, attr)))
这将从超类命名空间中复制所有不以 _
开头的内容。在实践中,人们可能希望应用更严格的规则。
定义子类时__init_subclass__
自动运行。这意味着子类无需 运行 显式编码即可获得复制的属性。
class B(A):
pass
class C(A):
c = 3
assert B.a is not A.a
assert C.a is not A.a