如何从python中的类属性分配方法装饰器?

2024-10-16 20:45:18 发布

您现在位置:Python中文网/ 问答频道 /正文

所以,我知道我可以毫不费力地做到:

button = widget.libray.Button()

class X():
  @button.on_click
  def click(self, event):
    ...

没有问题。在

…但这很烦人,因为现在“button”不在类的范围内;我希望这是一个类属性。如何为类成员使用@blah decorate语法?在

我当然不能用装修工,像这样:

^{pr2}$

我的意思是,我看到了问题;当类被定义时,方法是在类上定义的(我猜),所以即使您在init()步骤中创建小部件,它在类定义被解析的时候并不存在,因此它在那时不能用作装饰器。在

我想知道是否有办法解决这个问题?在

当然,在很多情况下,您希望decorator属性引用附加到类的某个实例?在

(从我上面的例子中可以看出,这个不仅仅是一个“如果”的情况;这是本周我第二次使用冗长的语句自我功能= self.instance.12月(自我功能)表格)

有什么建议吗?在

(……显然,除了使用那些因为愚蠢而不这么做的库;这不是真正的解决方案。:P)


Tags: self功能event属性定义ondef情况
2条回答

在我看来,当你不需要装饰的时候,你就想装饰它,这让我感到困惑。您真正需要做的是注册一个回调。除了注册它之外,还没有必要装饰回调。在

只需将按钮作为成员,就像您已经拥有的那样,并向它注册回调。在

def on_enter(self):
    self.b = Button(text='Hello World')
    b.event(self.bt) # register, don't decorate

而且,不能使用修饰符(除非创建一个全局Button),因为装饰是在定义类时完成的,Button成员仅在创建对象时实例化,因此此时不能注册对它的回调。在

可以将按钮设为类属性:

class X():
  button = widget.libray.Button()

  @button.on_click
  def click(self, event):
    # blah

如果您尝试实例化X的多个实例(因为它们将共享同一个按钮),这当然会导致问题,但是如果您全局定义了button,那么这已经是一个问题了。在

不过,您已经准确地诊断出了问题:修饰发生在类定义时,但您希望方法与实例相关联。最终,试图用这些伎俩来强迫它很可能会令人困惑。您正在创建的按钮实例在概念上与X的实例关联,而不是类本身。您可以合理地创建一个GUI类,您打算多次实例化它(对于某些特定样式的widget,或其他),在这种情况下,您必须放弃这些技巧,因为在您希望绑定事件时确实需要实例。在

如果你真的愿意,你可以想出一个更周密的方案来处理这个问题。例如,可以使用像@onclick('button')这样的装饰器,将名称button存储为方法对象的属性。然后,您可以在__init__中使用代码来迭代对象的方法,并将它们绑定到GUI小部件上具有相应名称的事件。(也就是说,创建一个按钮并将其存储self.button,然后__init__将此属性的名称与传递给装饰器的名称链接起来,并绑定事件。)

然而,做一件显而易见的事情可能更简单:不要尝试花哨地使用decorator在类级别处理特定于实例的行为。只需在方法代码中绑定事件,如第二个示例所示。在

相关问题 更多 >