Python 如何从装饰器获取对实例方法的引用
我一直在使用GUI库,该库允许您使用connect函数将信号连接到信号处理程序,例如:Python 如何从装饰器获取对实例方法的引用,python,callback,signals,decorator,Python,Callback,Signals,Decorator,我一直在使用GUI库,该库允许您使用connect函数将信号连接到信号处理程序,例如: widget.connect(signal, callback) 意味着每当小部件触发信号时,将运行函数回调。为了使我的代码变得更好,并从构造函数中删除一系列的connect调用,我决定使用一个decorator,它工作得很好: def callback(widget, signal) def decorate(f): widget.connect(signal, f)
widget.connect(signal, callback)
意味着每当小部件触发信号时,将运行函数回调
。为了使我的代码变得更好,并从构造函数中删除一系列的connect
调用,我决定使用一个decorator,它工作得很好:
def callback(widget, signal)
def decorate(f):
widget.connect(signal, f)
return f
return decorate
...
@callback(widget, signal)
def do_something():
...
在我需要在一个类中执行此操作之前,它一直工作得很好-函数在绑定到该类之前被修饰,这意味着给定的回调函数没有得到拥有它的类的实例,这使得它毫无用处。有什么方法可以让它工作吗?一个相对简单的解决方案是可能的。我们首先使用decorator来标记函数。构造实例时,我们搜索这些标记并注册回调 更具体地说,mark-and-recapture模式的工作原理是使用decorator在绑定函数之前对其进行标记,然后在构造函数中实例的绑定方法中找到它 首先,我们使用装饰器进行标记(我们使用一个集合来允许在一个方法上使用多个标记): 然后,我们使用查找标记函数的绑定版本,并连接它们:
def connect_callbacks(obj):
for _, f in inspect.getmembers(obj, inspect.ismethod):
try:
marks = f.__func__._marks
except AttributeError:
continue
for widget, signal in marks:
widget.connect(signal, f)
\uuuu func\uuu
是原始未绑定函数的名称。这使我们能够访问我们早些时候应用的标记,便于我们重新捕获
然后,我们可以简单地创建类并修饰函数,记住在构造函数中连接回调:
class Test:
def __init__(self):
...
connect_callbacks(self)
@callback(widget, signal)
def test():
...
这允许我们将绑定的方法与装饰器连接起来
编辑:我已经在github上发布了一个小型库,它为您提供了这个功能,名为
class Test:
def __init__(self):
...
connect_callbacks(self)
@callback(widget, signal)
def test():
...