Ссылка на метод в атрибуте перед определением метода вызывает ошибку - PullRequest
0 голосов
/ 26 ноября 2018

Я не понимаю, почему это работает;

class parentClass(object):
    pass

class childClass(parentClass):

    def my_meth(var):
        print(var)

    a = {'meth': my_meth}

x = childClass.a['meth']("Helloworld")

Пока это не удается;

class parentClass(object):
    pass

class childClass(parentClass):

    a = {'meth': my_meth}

    def my_meth(var):
        print(var)

x = childClass.a['meth']("Helloworld")

может показаться , что класс читается построчнострока выполнения, и если определение метода не было проанализировано до того, как на него ссылаются в атрибуте, возникает ошибка?

Это правда?Почему это происходит в атрибутах класса / статики, в то время как вы можете определять методы в любом порядке и ссылаться на них из других методов, написанных выше или ниже их?

Есть ли способ сохранить атрибуты класса наверху классасохранить читабельность и последовательную разметку?

1 Ответ

0 голосов
/ 26 ноября 2018

Может показаться, что класс читается построчно при выполнении, и если определение метода не было проанализировано до того, как на него ссылаются в атрибуте, возникает ошибка?

Да, это правда.Определения классов выполняются сверху вниз, как код уровня модуля.Вы даже можете помещать такие вещи, как операторы if / else и циклы for непосредственно внутри тела класса.

Есть ли способ сохранить атрибуты класса в верхней части класса, чтобы сохранить читабельность и согласованное расположение?

Ваш первый пример в порядке.Порядок не считается странным в Python.

Тем не менее, у вас есть потенциальные альтернативы.Вы можете, например, создать @classmethod для инициализации атрибутов класса в верхней части класса, а затем вызвать сразу после объявления класса, например,

class childClass(parentClass):

    @classmethod
    def _initialize(cls)
        cls.a = {'meth': cls.my_meth}

    def my_meth(var):
        print(var)

childClass._initialize()

Вы можете даже написать декоратор класса, чтобы сделатьэтот шаг для вас (если вы считаете, что это красивее), поскольку они выполняются после того, как код объявления класса завершил выполнение.

Почему это происходит в атрибутах класса / статики, тогда как вы можете определять методы в любом порядкеи ссылаться на них из других методов, написанных выше или ниже их?

Выполнение функции Definition отличается от вызова функции object , которую она создает.Первый просто создает объект функции и присваивает его имя локальному контексту.Последний запускает свой код.

Классы - просто причуды.Вы можете менять и изменять атрибуты во время выполнения.Когда вы делаете self.foo() внутри метода bar, оператор . выполняет поиск атрибута атрибута foo объекта self.Это аналогичная идея при использовании cls.foo() в методе класса.

Вполне возможно написать функцию, которая ссылается на атрибут, который не существует.Конечно, с ошибкой AttributeError произойдет, если вы ее вызовите, но если каким-то образом атрибут будет установлен позже, вы можете вызвать его успешно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...