简体   繁体   English

Python:确保 class 属性不在常见 inheritance 树之间共享

[英]Python: ensure class attributes are not shared between common inheritance trees

I have the feeling I've seen this somewhere, but am not longer sure whether that's a re-constructed memory or if it really exists.我感觉我在某处看到过这个,但我不再确定这是重建的 memory 还是真的存在。 In any case I cannot find a reference to this situation:在任何情况下,我都找不到这种情况的参考:

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

In the above example, Aa is Ba is C.a .在上面的例子中, Aa is Ba is C.a But, I actually wanted them to be separate while keeping this structure.但是,我实际上希望它们在保持这种结构的同时分开。 There is a good reason for this and I don't want to discuss instance variables.这是有充分理由的,我不想讨论实例变量。 The reason for that is that in my application all these classes are used as 'namespaces'.原因是在我的应用程序中,所有这些类都用作“命名空间”。 To solve the 'issue', I replace A inherited parts by a copy of itself as (pseudo code):为了解决“问题”,我将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

Define __init_subclass__ to automatically copy superclass-attributes when a childclass is defined.定义__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)))

This will copy everything from the superclass namespace that does not start with _ .这将从不以_开头的超类命名空间中复制所有内容。 In practice, one might want to apply more restrictive rules.在实践中,人们可能希望应用更严格的规则。

The __init_subclass__ is automatically run when a subclass is defined. __init_subclass__在定义子类时自动运行。 This means subclasses gain the copied attributes without having to run code explicitly.这意味着子类无需显式运行代码即可获得复制的属性。

class B(A):
    pass

class C(A):
    c = 3

assert B.a is not A.a
assert C.a is not A.a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM