假设我有一个基类,__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
为什么呢?我真的无法理解。
答案 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
,因此您实际上并没有覆盖任何内容,只是引入了一个新变量。
如果您希望变量可以覆盖,请不使用盯着两个下划线的名称。