【问题标题】:Share class attributes among several classes in Python在 Python 中的多个类之间共享类属性
【发布时间】:2014-07-22 15:31:04
【问题描述】:

我有一个包含类属性的类。我需要它们被一组其他类作为类属性共享,这样如果它们中的任何一个修改了这些属性,它们都会被修改。我天真地尝试使用继承,但它不是那样工作的:每个类的行为都好像它有自己的这些类属性的“副本”。

文件:

# baseClass.py 
class BaseClass(object):
    iden = 0


# child1.py 
from baseClass import BaseClass

class Child1(BaseClass):
    @classmethod
    def getId(cls):
        return cls.iden


# child2.py
from baseClass import BaseClass

class Child2(BaseClass):
    @classmethod
    def getId(cls):
        return cls.iden

我用来测试的文件是:

from child1 import Child1
from child2 import Child2

print(Child1.getId()) 
Child1.iden = 5
print(Child1.getId())
print(Child2.getId())

我看到的输出:

0
5
0

我应该怎么做,让 Child1、Child2 和 BaseClass 共享 iden 类属性?

【问题讨论】:

    标签: python class-attributes


    【解决方案1】:

    试试这个:

    # baseClass.py 
    class BaseClass(object):
        iden = 0
        @classmethod
        def set_id(cls, id):
            BaseClass.iden = id
    

    你可以这样称呼它:

    Child1.set_id(5)
    

    【讨论】:

    • 谢谢,它既简单又有效。虽然我会尝试使用 Jamie 的解决方案,作为深入研究元编程的借口。
    【解决方案2】:

    您可以通过将iden 属性添加到BaseClass 的元类来做到这一点:

    class BaseType(type):
        _iden = 0
        def _get_iden(cls):
            return BaseType._iden
        def _set_iden(cls, value):
            BaseType._iden = value
        iden = property(_get_iden, _set_iden)
    
    class BaseClass(object):
        __metaclass__ = BaseType
    
    class Child1(BaseClass):
        pass
    
    class Child2(BaseClass):
        pass
    
    print Child1.iden
    Child1.iden = 5
    print Child1.iden
    print Child2.iden
    

    输出:

    0
    5
    5
    

    【讨论】:

    • @zeycus 没问题,但您可能需要考虑其他人所说的为什么您想要这个设计。
    【解决方案3】:

    我不会使用继承。如果您确实需要更改Child1Child2 的属性,您也可以使用__setattr__ 并更改基类的属性。不过我不建议这样做……在我看来,设计中存在一些问题。为什么需要更改孩子的属性?也许你想添加一个新的类来保存这个属性,并且所有其他类都会引用它?

    据我了解,以下内容应该适合您的情况:

    # baseClass.py 
    class BaseClass(object):
    
        def initializeIden():
            # Do some initialization
            BaseClass.iden = 0
    
    
    # child1.py 
    from baseClass import BaseClass
    
    class Child1:
        @classmethod
        def getId(self):
            if not hasattr(BaseClass, "iden"):
                BaseClass.initializeIden()
            return BaseClass.iden
    
    
    # child2.py
    from baseClass import BaseClass
    
    class Child2(BaseClass):
        @classmethod
        def getId(self):
            if not hasattr(BaseClass, "iden"):
                BaseClass.initializeIden()
            return BaseClass.iden
    

    【讨论】:

    • 实际上是所有IS共享的类属性作为对类实例的引用。我想要的是确保它始终是共享的,并且不会创建两个 Class 实例。首先,我虽然应该使用单例模式,但事实是在其他情况下,我希望有可能创建多个 Class 实例。但无论如何,也许你是对的,我应该重新考虑设计。
    • 是否需要更改子类的属性?您只能在基类中拥有它并从那里更改它。使用继承,您将破坏 SOLID 原则之一 - Liskov substitution principle。至少在我看来,情况会是这样……
    • 脚本启动时,属性为None。任何子类都可能需要创建它,一旦完成,我希望它可用于所有其他子类。没有必要再改了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    相关资源
    最近更新 更多