Почему переменная класса даже
доступно в экземпляре класса 'c ()'
без префикса class ?
Вы можете с пользой думать об этом как об экземплярах, "наследующих" от своего класса. IOW, когда атрибут с именем 'atr'
ищется в экземпляре x
(например, x.atr
), если он не найден в самом экземпляре, он затем ищется в классе (что, в свою очередь, может вызвать поиск в базах класса) вверх по цепочке mro
).
В какой ситуации он используется?
Самый распространенный случай:
class sic(object):
def foo(self): ...
x = sic()
x.foo()
Вы не можете думать о foo
как о «переменной класса», но это потому, что термин «переменная» действительно бессмыслен в Python, который скорее имеет дело с names и attribute . В данной лексической области не существует отдельного пространства имен для вызываемых и не подлежащих вызову объектов: все они совместно используют одинаковое пространство имен.
Так, например, если вы сделали x.foo = 23
, вы больше не могли бы звонить x.foo()
- потому что поиск x.foo
даст вам значение 23
, а это int
, не вызывается.
Еще один способ взглянуть на это -
class one(object):
foo = lambda self: ...
class two(object):
def foo(self): ...
class three(object):
foo = 23
глубокой разницы нет - все они позволяют установить атрибут класса foo
(один не вызывается, два - один, один связан с оператором def
, два - с присваиваниями; различия - не глубоко с точки зрения поиска атрибутов в экземплярах этих классов).
Типичное использование для не подлежащих вызову атрибутов может быть:
class zap(zop):
zep = None
def blub(self):
if self.zep is None: self.zep = 23
...&c...
Нет необходимости давать zap
__init__
с self.zep = None
и делегирование суперклассу __init__
(если есть) - проще просто наследовать zop
'__init__
(если есть) и используйте атрибут класса настолько долго, насколько это возможно (вместо этого он станет атрибутом экземпляра тогда и только тогда, когда blub
вызывается для этого экземпляра - также может сэкономить немного памяти для экземпляров, для которых blub
никогда не вызывается; ).