我知道在这个主题上有类似的问题,但它们似乎都不适用于我的案例 为什么下面的代码会打印None而不是True? 感谢
class A(object):
flag = None
@classmethod
def set_flag(cls):
cls.flag = True
class B(A):
@classmethod
def print_super_flag(cls):
print cls.__bases__[0].flag # This prints None
print super(B, cls).flag # This also
if __name__ == "__main__":
b = B()
b.set_flag()
b.print_super_flag()
答案 0 :(得分:1)
这个电话:
b.set_flag()
您将set_flag
定义为:
@classmethod
def set_flag(cls):
cls.flag = True
因此,当b
调用set_flag
时,cls
为B
- 所以它设置B.flag
,而不是A.flag
。然后,当您打印A.flag
时,它是None
,因为您从未触及它。因此print_super_flag
中的问题根本不存在 - 您在那里正确访问A.flag
。两次。
如果您将set_flag
定义为:
class A(object):
flag = None
@classmethod
def set_flag(cls):
A.flag = True
您的代码打印出True
(两次),因为set_flag
现在在派生类中设置了A.flag
。当然,此时你的方法是classmethod
是没有实际意义的,但这是你期望方法执行的函数;当您从派生类调用classmethod
时,cls
派生类,而不是父类。
答案 1 :(得分:0)
试试这个稍微扩展的版本,看看发生了什么:
class A(object):
flag = None
@classmethod
def set_flag(cls):
cls.flag = True
class B(A):
@classmethod
def print_super_flag(cls):
print cls.__bases__[0].flag # This prints None
print super(B, cls).flag # This also
if __name__ == "__main__":
b = B()
b.set_flag()
print b.flag
b2 = B()
print b2.flag
a = A()
print a.flag
打印:
True # because you set b.flag
True # because b.flag and b2.flag refer to the same class variable, B.flag
None # because B.flag and A.flag are NOT the same class variable
基本上,子类(B
)有自己的flag
类变量副本,而不是与父类(A
)共享。
更多细节here,假设您使用的是Python 2.7-ish。
答案 2 :(得分:0)
如果您只希望只有一个标记属性是基类的一部分,则需要将set_flag()
方法更改为:
class A(object):
flag = None
@classmethod
def set_flag(cls):
A.flag = True
由于修订后的方法没有引用其cls
参数,您可以将其staticmethod
并删除参数,尽管这并不是非常重要。无论如何,通过对基类进行硬编码,您可以确保设置了哪个flag
属性,否则将创建另一个标志属性作为cls
参数的一部分,这是调用的类。
由于只存在一个类属性,因此将打印其值。