Я хотел бы иметь возможность определять переменную класса (как-то в базовом классе), которая присутствует, но не разделяется между подклассами или экземплярами. То, что я сначала попытался было следующее:Переменные класса и наследование в Python
from __future__ import print_function # For lambda print()
class CallList(list):
def __call__(self, *args, **kwargs):
for f in self:
f(*args, **kwargs)
class State:
on_enter = CallList()
def enter(self):
self.on_enter()
class Opening(State): pass
class Closing(State): pass
Opening.on_enter.append(lambda: print('Opening state entered'))
Closing.on_enter.append(lambda: print('Closing state entered'))
но поведение подклассов и экземпляров подкласса, чтобы ссылаться на переменном класс базовых классов, что дает мне следующее:
opening = Opening()
closing = Closing()
opening.enter()
# Actual output: Opening state entered
# Closing state entered
# Desired output: Opening state entered
opening.on_enter.append(lambda: print('Additional instance callback'))
opening.enter()
# Actual output: Opening state entered
# Closing state entered
# Additional instance callback
# Desired output: Opening state entered
# Additional instance callback
closing.enter()
# Actual output: Opening state entered
# Closing state entered
# Additional instance callback
# Desired output: Closing state entered
Я понимаю, почему это (я ожидал, что что-то отличное от опыта - это другие языки, но это прекрасно).
Возможно ли изменить класс Base (а не подклассы), чтобы каждый из подклассов имел свою собственную копию переменной класса, а для экземпляров подклассов - получить копию их переменных классов, которая может затем независимо изменять, не разделяя также?
Я не понимаю, почему открытия и закрытие подклассов, и почему on_enter должны быть переменным класс. Если on_enter - это переменная экземпляра, а открытие и закрытие - это экземпляры состояния, все будет работать нормально. – RemcoGerlich
Возможно, вы можете написать метакласс для базового класса, который гарантирует, что подклассы не «наследуют» определенные переменные. – doublep
Вы можете сделать каждый * класс * отдельным атрибутом класса с метаклассом (см., Например, http://stackoverflow.com/q/100003/3001761), но если каждый * экземпляр * должен иметь отдельный атрибут, почему бы не сделать его атрибут экземпляра? – jonrsharpe