Python - 在派生类中重新定义类属性

时间:2013-10-15 09:06:54

标签: python inheritance

假设我有一个基类,__flag可以访问@classmethod属性。

class Base(object):
    __flag = None

    def __init__(self) :
        pass

    @classmethod
    def flag(self):
        return self.__flag

假设我还有一个派生类,我在其中更改属性。

class Derived(Base):
    __flag = True

然后,当我尝试访问派生类的属性时,我得到了基类的属性:

In [3]: print Derived.flag()
None

为什么呢?我真的无法理解。

3 个答案:

答案 0 :(得分:3)

这是因为Python中的“隐藏”变量存储方式不同。那里有一点魔力。

以下是一个不起作用的原因示例:

class Base(object):
    __flag = 'base'
    _other_flag = 'base'

    def __init__(self) :
        pass

    @classmethod
    def flag(self):
        return self.__flag

    @classmethod
    def other_flag(self):
        return self._other_flag

class Derived(Base):
    __flag = 'derived'
    _other_flag = 'derived'

print 'base flag', Base.flag()
print 'derived flag', Derived.flag()
print 'base other flag', Base.other_flag()
print 'derived other flag', Derived.other_flag()

# Note the following 2 statements:
print 'base flag property', Derived._Base__flag
print 'derived flag property', Derived._Derived__flag

print 'base other flag property', Base._other_flag
print 'derived other flag property', Derived._other_flag

正如您在底部看到的那样,它存储在一个不同的变量中,并以Base.flag方法静默转换为。{/ p>

答案 1 :(得分:2)

__移除__flag,它会很好用。像这样:

class Base(object):
    flagAtt = None

    def __init__(self) :
       pass

    @classmethod
    def flag(self):
        return self.flagAtt

class Derived(Base):
    flagAtt = True

给出了:

>>> print Derived.flag()
True
>>> print Base.flag()
None

答案 2 :(得分:1)

Python对以两个下划线开头的变量执行名称修改(除了以两个下划线结尾的那些),因此__flag中的Base与{{ 1}}。您可以使用__flag

来观察此情况
dir

此处>>> class Base(object): ... __flag = True ... >>> dir(Base) ['_Base__flag', '__class__', '__delattr__', ...... # lots of others 变量已变为__flag。在_Base__flag中,它变为Derived,因此您实际上并没有覆盖任何内容,只是引入了一个新变量。

如果您希望变量可以覆盖,请使用盯着两个下划线的名称。