从派生类重新绑定基类中的不可变类属性

2024-04-24 12:03:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我在python中遇到了一个通用的问题。基类定义一个类属性class_attr。这个属性是不可变的,在本例中它是一个数字。我想将这个属性从派生类中更改,从而将Base.class_attr重新绑定到新值(在我的玩具案例中,增加它)。你知道吗

问题是如何做到这一点而不显式地在语句Base.class_attr += 1中命名Base。你知道吗

class Base(object):
    # class attribute: 
    class_attr = 0

class Derived(Base): 
    @classmethod
    def increment_class_attr(cls):        
        Base.class_attr += 1 
        # is there a solution which does not name the owner of the 
        # class_attr explicitly?

        # This would cause the definition of Derived.class_attr, 
        # thus Base.class_attr and Derived.class_attr would be 
        # two independent attributes, no more in sync:
    #   cls.class_attr += 1

Derived.increment_class_attr()
Derived.increment_class_attr()

print Base.class_attr # 2

请注意:我想问的是一个非常重要的问题,即我是否可以重新绑定父类的属性。我不是在寻找解决这个问题的方法(例如,将increment_class_attr移到Base)。你知道吗


Tags: ofthebase属性定义数字基类class
1条回答
网友
1楼 · 发布于 2024-04-24 12:03:35

使用__bases__属性:

In [68]: class Base(object):
    ...:     # class attribute: 
    ...:     class_attr = 0
    ...:     

In [69]: class Derived(Base):
    ...:     @classmethod
    ...:     def inc(cls):
    ...:         p, = cls.__bases__
    ...:         p.class_attr += 1
    ...:         

In [70]: Base.class_attr
Out[70]: 0

In [71]: Derived.inc()

In [72]: Derived.inc()

In [73]: Base.class_attr
Out[73]: 2

如果您有多重继承:

In [88]: class DifferentInherited(object):
    ...:     class2_attr = 0
    ...: 


In [90]: class Der2(Base, DifferentInherited):
    ...:     @classmethod
    ...:     def inc(cls):
    ...:         print cls.__bases__
    ...:         a, b, = cls.__bases__
    ...:         print a.class_attr
    ...:         print b.class2_attr
    ...:         

In [91]: Der2.inc()
(<class '__main__.Base'>, <class '__main__.DifferentInherited'>)
2
0

假设您也不知道继承顺序,则需要为变量测试每个类:

In [127]: class Der3(DifferentInherited, Base):
     ...:     @classmethod
     ...:     def inc(cls):
     ...:         # This gets a list of *all* classes with the attribute `class_attr`
     ...:         classes = [c for c in cls.__bases__ if 'class_attr' in c.__dict__]
     ...:         for c in classes:
     ...:             c.class_attr += 1
     ...:             

In [128]: Der3.inc()

In [129]: Base.class_attr
Out[129]: 3

In [131]: DifferentInherited.class2_attr
Out[131]: 0

多重继承使用__mro__

In [146]: class Multi(Der3):
     ...:     @classmethod
     ...:     def inc(cls):
     ...:         c_attr =  [c for c in cls.__mro__ if 'class_attr' in c.__dict__]
     ...:         print c_attr
     ...:         c_attr[0].class_attr += 1
     ...:         

In [147]: Multi.inc()
[<class '__main__.Base'>]

In [148]: Base.class_attr
Out[148]: 4

相关问题 更多 >