Вот решение для "statefull объектов", которое я придумала, но оно довольно неэффективно для вашей предполагаемой цели, потому что изменения состояния относительно дороги. Однако это может хорошо работать для объектов, которые изменяют состояние нечасто или подвергаются лишь ограниченному числу изменений состояния. Преимущество состоит в том, что после изменения состояния избыточная косвенность отсутствует.
class T:
"""
Descendant of `object` that rectifies `__new__` overriding.
This class is intended to be listed as the last base class (just
before the implicit `object`). It is a part of a workaround for
* https://bugs.python.org/issue36827
"""
@staticmethod
def __new__(cls, *_args, **_kwargs):
return object.__new__(cls)
class Stateful:
"""
Abstract base class (or mixin) for "stateful" classes.
Subclasses must implement `InitState` mixin.
"""
@staticmethod
def __new__(cls, *args, **kwargs):
# XXX: see https://stackoverflow.com/a/9639512
class CurrentStateProxy(cls.InitState):
@staticmethod
def _set_state(state_cls=cls.InitState):
__class__.__bases__ = (state_cls,)
class Eigenclass(CurrentStateProxy, cls):
__new__ = None # just in case
return super(__class__, cls).__new__(Eigenclass, *args, **kwargs)
# XXX: see https://bugs.python.org/issue36827 for the reason for `T`.
class StatefulThing(Stateful, T):
class StateA:
"""First state mixin."""
def say_hello(self):
self._say("Hello!")
self.hello_count += 1
self._set_state(self.StateB)
return True
def say_goodbye(self):
self._say("Another goodbye?")
return False
class StateB:
"""Second state mixin."""
def say_hello(self):
self._say("Another hello?")
return False
def say_goodbye(self):
self._say("Goodbye!")
self.goodbye_count += 1
self._set_state(self.StateA)
return True
# This one is required by `Stateful`.
class InitState(StateA):
"""Third state mixin -- the initial state."""
def say_goodbye(self):
self._say("Why?")
return False
def __init__(self, name):
self.name = name
self.hello_count = self.goodbye_count = 0
def _say(self, message):
print("{}: {}".format(self.name, message))
def say_hello_followed_by_goodbye(self):
self.say_hello() and self.say_goodbye()
# ----------
# ## Demo ##
# ----------
if __name__ == "__main__":
t1 = StatefulThing("t1")
t2 = StatefulThing("t2")
print("> t1, say hello.")
t1.say_hello()
print("> t2, say goodbye.")
t2.say_goodbye()
print("> t2, say hello.")
t2.say_hello()
print("> t1, say hello.")
t1.say_hello()
print("> t1, say hello followed by goodbye.")
t1.say_hello_followed_by_goodbye()
print("> t2, say goodbye.")
t2.say_goodbye()
print("> t2, say hello followed by goodbye.")
t2.say_hello_followed_by_goodbye()
print("> t1, say goodbye.")
t1.say_goodbye()
print("> t2, say hello.")
t2.say_hello()
print("---")
print( "t1 said {} hellos and {} goodbyes."
.format(t1.hello_count, t1.goodbye_count) )
print( "t2 said {} hellos and {} goodbyes."
.format(t2.hello_count, t2.goodbye_count) )
# Expected output:
#
# > t1, say hello.
# t1: Hello!
# > t2, say goodbye.
# t2: Why?
# > t2, say hello.
# t2: Hello!
# > t1, say hello.
# t1: Another hello?
# > t1, say hello followed by goodbye.
# t1: Another hello?
# > t2, say goodbye.
# t2: Goodbye!
# > t2, say hello followed by goodbye.
# t2: Hello!
# t2: Goodbye!
# > t1, say goodbye.
# t1: Goodbye!
# > t2, say hello.
# t2: Hello!
# ---
# t1 said 1 hellos and 1 goodbyes.
# t2 said 3 hellos and 2 goodbyes.
Я разместил «запрос на замечания» здесь .