所以我有一个按钮类,当单击该按钮类时会执行某些操作,但是不同的按钮执行不同的功能。我想知道Python中是否存在诸如匿名内部类之类的东西来覆盖此类回调,而不必为每种类型的按钮创建新的类。我知道我可以分配一个回调属性来调用这样的函数,但是我只是想知道是否有一个匿名内部类等效项。
class Button:
def __init__(self):
# set image here
def update(self):
if mouse_clicked():
# do something
在Java中,我可以创建匿名内部类来覆盖update方法以关闭,播放,暂停和所有其他按钮,而无需创建完全不同的类。
class Button {
Button() {
// set image here
}
public void update() {
if mouse_clicked() {
// do something
}
}
}
最佳答案
当然,您可以(尽管可能不应该)仅使用type
:
In [1]: class Button:
...: def callback(self):
...: print('Hello')
...:
In [2]: button = type('', (Button,), {'callback': lambda self: print('World')})()
In [3]: button.callback()
World
您可能更希望在表达式之外定义函数,以便避免对代码进行代码搜索:
In [5]: def callback(self):
...: print('World')
...: button = type('', (Button,), {'callback': callback})()
...:
In [6]: button.callback()
World
这确实可以完成Java所做的事情,但是这样做的意义更加明确,因此语法也更加繁琐。实际上,您可以在python中定义本地类:
In [7]: def function():
...: class MyButton(Button):
...: def callback(self):
...: print('Hello, from a local class!')
...: return MyButton()
...:
In [8]: button = function()
In [9]: button.callback()
Hello, from a local class!
与Java的唯一区别在于,您必须为该类命名并使用它来创建实例。使用装饰器可以避免最后一步:
def auto_instantiator(*args, **kwargs):
def decorator(cls):
return cls(*args, **kwargs)
return decorator
用作:
In [2]: class Button:
...: def callback(self):
...: print('Button')
...:
In [3]: @auto_instantiator() # here args that should be passed to __init__
...: class button(Button):
...: def callback(self):
...: print('New Button')
...: # no need for button = button(...)
In [4]: button.callback() # button is an *instance* of the button class
New Button
但是,根据您将如何使用该方法,我建议使用两种不同的方法来解决该问题:
实际上,除了某些数据外,按钮的所有操作都是相同的。在这种情况下,最好创建一个实例属性(或属性)来保存该数据,然后更改数据而不是方法:
我的意思是这样的:
class Greeter:
def __init__(self, name):
self.name = name
def greet(self):
print('Hello, {.name}'.format(self))
您可以将instance属性设置为所需的回调:
button.callback = new_callback