Python 传递类变量时类对象中的装饰器
我想知道如何在可以接受类变量的类中设置装饰器。我认为这可能有用的例子是在Pyside/PyQt中,我需要在函数的开始和结束时阻止和取消阻止小部件上的信号 例如:Python 传递类变量时类对象中的装饰器,python,pyqt4,decorator,pyside,Python,Pyqt4,Decorator,Pyside,我想知道如何在可以接受类变量的类中设置装饰器。我认为这可能有用的例子是在Pyside/PyQt中,我需要在函数的开始和结束时阻止和取消阻止小部件上的信号 例如: class Window(QtGui.QMainWindow): .... def updateList(self, *args): self.list.blockSignals(False) //do things on self.list self.list.bloc
class Window(QtGui.QMainWindow):
....
def updateList(self, *args):
self.list.blockSignals(False)
//do things on self.list
self.list.blockSignals(True)
现在,在不同的小部件上有很多地方可以实现这一点。当然,我可以用这种方法来阻止和取消阻止每个项目,但那很乏味。我必须记住,当我完成时,要解除所有的封锁
进入另一个步骤,我可以将块移动到它自己的功能中
class Window(QtGui.QMainWindow):
....
def updateList(self, *args):
self.block([self.list])
//do things on self.list
self.block([self.list])
def block(self, items):
for item in items:
if item.signalsBlocked():
item.blockSignals(False)
else:
item.blockSignals(True)
好极了!我可以在我的代码中添加这一点,感觉非常有用。但我觉得这里缺少某种最终的老板形式,使其真正在全球范围内有用。就像某种装潢师
使用这个答案,我可以将变量传递给我的装饰器并装饰我的函数!
现在我觉得这真的很有用!除了,@block([self.list])不知道self是什么
所以,我想做的是,假设我能做到这一点,这合理吗?可能吗,还是我在追逐野龙?如果可能,正确的方法是什么?您不能在类定义时引用属性值,但可以使用它们的名称:
def block(*attrs):
def dec(fn):
@functools.wraps(fn)
def wrap(self,*args,**kwargs):
for a in attrs: getattr(self,a).blockSignals(True)
ret=fn(self, *args, **kwargs)
for a in attrs: getattr(self,a).blockSignals(False)
return ret
return wrap
return dec
不得不写作有点难看
class Window(QtGui.QMainWindow):
@block("list1","list2")
def updateList(self, *args): # ...
使用字符串引号和all,但它可以工作。这里是一个简单的上下文管理器,用于比较:
class blocked(object):
def __init__(self, *targets):
self._targets = targets
def __enter__(self):
for target in self._targets:
target.blockSignals(True)
def __exit__(self, cls, exception, traceback):
for target in self._targets:
target.blockSignals(False)
下面是如何使用它:
class Window(QtGui.QMainWindow):
...
def updateList(self, *args):
with blocked(self.list):
# do things with self.list
这样做的好处是
blocked
可以在任何地方使用,并且可以动态指定目标。也可以说它更具可读性,因为被阻止的是self.list
(信号发射器),而不是self.updateList
@DavisHerring啊,是的,我又看了另一个答案,我修正了它。(清理注释…)这应该是一个上下文管理器,而不是一个装饰器。这样做会更加灵活,因为它不会与任何特定的对象或函数/方法绑定。@ekhumoro:两者都可以。@ekhumoro您能举个例子吗?我对它们不熟悉,到目前为止做了一点研究,我有点困惑。我想我应该在wrap
中使用instance
作为参数名,而不是self
——但是…instance
会与wrapped函数中同名的参数冲突。函数wrap
将在描述符返回它时成为类的一个方法,self
对我来说似乎非常习惯。我可以立即看到在不应该为整个函数阻塞信号的情况下,它的用处。在这些示例中,装饰器会屏蔽整个函数。
class Window(QtGui.QMainWindow):
...
def updateList(self, *args):
with blocked(self.list):
# do things with self.list