Может показаться, что класс читается построчно при выполнении, и если определение метода не было проанализировано до того, как на него ссылаются в атрибуте, возникает ошибка?
Да, это правда.Определения классов выполняются сверху вниз, как код уровня модуля.Вы даже можете помещать такие вещи, как операторы 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
произойдет, если вы ее вызовите, но если каким-то образом атрибут будет установлен позже, вы можете вызвать его успешно.