1

假设我有一个基类,其中有__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

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

4

3 回答 3

4

这是因为 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方法中默默地转换为该变量。

于 2013-10-15T09:16:29.210 回答
2

删除__from __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
于 2013-10-15T09:12:45.240 回答
1

Python 对以两个下划线开头的变量执行名称修改(除了那些以两个下划线结尾的变量),因此__flaginBase不同于__flag. 您可以使用以下方法观察这一点dir

>>> class Base(object):
...     __flag = True
... 
>>> dir(Base)
['_Base__flag', '__class__', '__delattr__', ......   # lots of others

__flag变量变成了这里_Base__flag。在Derived它变成了_Derived__flag,所以你实际上并没有覆盖任何东西,只是引入了一个新变量。

如果您希望变量可被覆盖,请不要使用带有两个下划线的名称。

于 2013-10-15T09:17:43.327 回答