Переопределение переменных класса в python - PullRequest
14 голосов
/ 21 января 2011

Я пытаюсь немного понять, как 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 ... Есть ли способ перезаписать его?Почему это не перезаписывается?

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

Ответы [ 2 ]

12 голосов
/ 22 января 2011
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 голосов
/ 22 января 2011

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

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

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

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

...