猿问

装饰器替换重复的面向对象的代码?

我正在使用Qt / PySide开发一个GUI,其中包含许多处理各种小部件的单独类。每个小部件都管理按钮和其他用户输入之间的信号。我发现自己不得不在方法功能开始时重用代码来阻止小部件信号,然后在最后释放信号。我决定尝试写一个普通的装饰器来为我做这件事。

我已经搜索了SO并尝试以很少的使用装饰器的经验来实现最佳效果,因此我对自己的解决方案不满意。

我的问题是,编写通用装饰器的最佳方法是什么,该装饰器可以访问和运行该类中遵循清晰格式的方法?无论如何,我的方法好吗?


ibeautiful
浏览 126回答 1
1回答

白衣非少年

您正在寻找getattr:import functoolsdef blockSignals(*widgetnames):    def decorator(func):        @functool.wraps(func)        def method(self, *args, **kwargs):            widgets = [getattr(self.widget, name) for name in widgetnames]            for widget in widgets:                widget.blockSignals(True)             result = func(self, *args, **kwargs)            for widget in widgets:                widget.blockSignals(False)            return result        return method    return decoratorclass WidgetController(...):    def __init__(...):       self.widget.myWidget.currentIndexChanged.connect(reactToChange)    @blockSignals('myWidget')    def reactToChange(...):        ...    @blockSignals('anotherWidget', 'alsoBlockThisWidget')    def anotherFunction(...):        ...您必须传递窗口小部件的名称,而不是窗口小部件本身,因为方法是在定义类时定义的,而不是在实例化实例时定义的。实例self和实际的窗口小部件在self.widget类定义时不存在。该functools.wraps装饰机拷贝原函数的名称及其文档字符串的装饰功能。
随时随地看视频慕课网APP

相关分类

Python
我要回答