Если вы извлекаете классы из класса, определяющего вашу переменную (и, вероятно, метода, присваивающего ей), используя type(self)
, вы сохраняете (новое значение) атрибут в фактическом классе объекта.Это может быть очень полезно, но в вашем примере это , безусловно, неправильно .
Использование метода класса - то же самое, за исключением того, что подкласс может переопределить метод:это может заставить сложный случай работать, но ничего не делает для исправления простого случая наследования.
Использование имени класса является простым, идиоматическим ответом и позволяет избежать путаницы с подклассами.В отсутствие беспокойства по поводу повторного связывания этого имени это должно быть по умолчанию даже без какого-либо наследования.Если вас это беспокоит, вы можете stash объект класса двумя различными способами:
class A:
counter=0
# use the magic behind super():
def _count1(): __class__.counter+=1
# inject the class object:
@staticmethod
def _count2(cls): cls.counter+=1
A._count2.__defaults__=A,
# inject via a closure:
def capture(cls):
def _count(): cls.counter+=1
return _count
A._count3=staticmethod(capture(A))
Трюк __class__
, конечно, можно использовать напрямую, без метода-оболочки, но это немного некрасиво;внутренне это очень похоже на последний подход с capture
.Одна вещь, которая не работает, - это попытаться создать функцию, которая ссылается на словарь класса , поскольку они защищены по причинам оптимизации.