如何从派生类中打印变量?

时间:2014-09-02 00:18:25

标签: python python-2.x super derived

我知道在这个主题上有类似的问题,但它们似乎都不适用于我的案例 为什么下面的代码会打印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()

3 个答案:

答案 0 :(得分:1)

这个电话:

b.set_flag()

您将set_flag定义为:

@classmethod
def set_flag(cls):
    cls.flag = True

因此,当b调用set_flag时,clsB - 所以它设置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参数的一部分,这是调用的类。

由于只存在一个类属性,因此将打印其值。