Переопределение переменных класса в python

Я пытаюсь понять, как 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()

Вывод: "значение по умолчанию в базе"

Мне было интересно, почему поле "default" не перегружено классом Descend... Есть ли способ переписать его? Почему он не перезаписывается?

Любая подсказка (или ссылка на пояснительную страницу будет оценена по достоинству). Спасибо!

Ответы

Ответ 1

Переменная класса переписывается. Попробуйте

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

Причина, по которой ваш путь не работает, больше связан с тем, как Python рассматривает аргументы по умолчанию для функций, чем с атрибутами класса. Значение по умолчанию для defl оценивается в момент, когда Python определяет привязку для showDefaultValue, и это делается ровно один раз. Когда вы вызываете свой метод, используется значение по умолчанию, которое было оценено во время определения.

В вашем случае defl привязано к значению переменной default, как это было во время выполнения формы тела класса Base. Независимо от того, как вы позже назовёте showDefaultValue (то есть через Base или через Descend), это значение остается фиксированным во всех последующих вызовах showDefaultValue.

Ответ 2

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)