在Python中重写类变量

15 投票
2 回答
17376 浏览
提问于 2025-04-16 10:24

我正在尝试了解一下Python(2.6)是如何处理类和实例的。在某个时刻,我试了以下这段代码:

#/usr/bin/python2.6

class Base(object):
    default = "default value in base"

    def __init__(self):
        super(Base, self).__init__()

    @classmethod
    def showDefaultValue(cls, defl = default):
        print "defl == %s" % (defl)


class Descend(Base):
    default = "default value in descend"

    def __init__(self):
        super(Descend, self).__init__()

if __name__ == "__main__":
    Descend.showDefaultValue()

输出结果是:“默认值在基类中”。

我在想,为什么“默认”这个字段没有被Descend类覆盖呢……有没有办法覆盖它?为什么它没有被覆盖?

任何提示(或者指向解释页面的链接)都非常感谢。谢谢!

2 个回答

13
def showDefaultValue(cls, defl=default):

这意味着default在函数定义的时候就会被计算,就像在Python中通常那样。所以定义看起来是这样的:

def showDefaultValue(cls, defl="default value in base"):

这个defl的值会作为默认参数存储在函数对象里,当你调用这个方法而不传任何参数时,就会使用这个默认值。你可以通过像print Descend.showDefaultValue.im_self.default这样的方式来查看函数的默认值,以验证这一点。

如果你想从当前类获取默认值,那么你需要从那里获取:

@classmethod
def showDefaultValue(cls, defl=None):
    if defl is None:
        defl = cls.default
    print "defl == %s" % (defl)
12

这个类变量被覆盖了。你可以试试

@classmethod
def showDefaultValue(cls):
    print "defl == %s" % (cls.default,)

你遇到的问题主要是因为Python处理函数默认参数的方式,而不是类属性的原因。defl的默认值是在Python定义showDefaultValue这个函数时就被计算出来的,而且这个计算只发生一次。当你调用这个方法时,使用的默认值就是在定义时计算出来的那个值。

在你的例子中,defl被绑定到了当时Base类体执行时default变量的值。无论你之后是通过Base还是Descend来调用showDefaultValue,这个值在后续的所有调用中都是固定不变的。

撰写回答