【发布时间】:2012-03-15 01:01:50
【问题描述】:
我定义了几个用于多重继承的类,例如:
class A:
def __init__(self, bacon = None, **kwargs):
self.bacon = bacon
if bacon is None:
self.bacon = 100
super().__init__(**kwargs)
class Bacon(A):
def __init__(self, **kwargs):
"""Optional: bacon"""
super().__init__(**kwargs)
class Eggs(A):
def __init__(self, **kwargs):
"""Optional: bacon"""
super().__init__(**kwargs)
class Spam(Eggs, Bacon):
def __init__(self, **kwargs):
"""Optional: bacon"""
super().__init__(**kwargs)
但是,我有多个类(例如,可能是 Bacon、A 和 Spam,但不是 Eggs)关心他们的属性 bacon 何时更改。他们不需要修改值,只需要知道新值是什么,就像一个事件一样。由于我设置了多重继承性质,这意味着必须通知超类有关更改(如果它关心的话)。
我知道如果我将类名传递给方法装饰器,或者如果我使用类装饰器,这可能是可能的。我不想拥有所有直接的自类引用,不得不在每个类之上创建大量装饰器,或者强制方法使用相同的名称,因为这些听起来都不是很pythonic。
我希望得到如下所示的语法:
@on_change(bacon)
def on_bacon_change(self, bacon):
# read from old/new bacon
make_eggs(how_much = bacon)
我不关心 bacon 的先前值,因此如果在设置 bacon 之后调用它,则不需要 bacon 参数。
是否可以检查一个超类是否有这个方法 装饰师?
如果这不可行,是否有替代传递事件的方法,例如 这个,通过多重继承链?
编辑:
Spam 中函数的实际调用将在 A 中完成,使用 @property 和 @bacon.setter,因为那将是初始化 bacon 的最上层类。一旦它知道在self 上调用什么函数,问题就只在于将调用传播到 MI 链上。
编辑 2:
如果我用@bacon.setter 覆盖属性,是否可以确定super() 类是否有bacon 的设置器?
【问题讨论】:
-
显然 OP 的意思是“{Detect if super() has a function} with a decorator”,而不是“Detect if super() has a {function with a decorator}”
-
None默认值主要用于当您实际上必须运行一些感兴趣的东西以获得默认值时。在这里,您可以只使用def foo(self, bacon=100, **kwargs): self.bacon = bacon,但如果您尝试支持在任意 kwargs 周围洗牌以真正取悦 OOP 小伙伴,则应该使用def __init__(self, **kwargs): self.bacon = kwargs.get('bacon', 100)。 -
@MikeGraham 培根参数可以从任何传递的
kwargs中删除,因为我认为默认的object不会对此感到满意。目的是在到达object时,每个参数都从kwargs中删除。 -
我忘记了新版本的 Python
object.__init__不像以前那样接受任意参数。
标签: python python-3.x decorator multiple-inheritance