2017-02-20 89 views
1

设计类时,我发现在类方法中,每次调用类方法时都会调用重复的步骤。例如,Python - 使用类方法来装饰其他类方法

class Queue(object): 
    def __init__(self): 
     self.connection = Connection() 

    def create(self, name): 
     self.probe = self.connection.plug() 
     self.probe.create(name) 
     self.probe.unplug() 

    def delete(self, name): 
     self.probe = self.connection.plug() 
     self.probe.delete(name) 
     self.probe.unplug() 

而且有很多方法需要类似的步骤来'插入'和'拔掉''探头'。在这种设计中,我们需要在每次执行操作时“插入”并“拔下”“探针”。

因此,我正在考虑由装饰者包装这些函数,以使代码看起来不那么重复。

class Queue(object): 
    def __init__(self): 
     self.connection = Connection() 

    def _with_plug(self, fn): 
     def wrapper(*args, **kwargs): 
      self.probe = self.connection.plug() 
      fn(*args, **kwargs) 
      self.probe.unplug() 

    @_with_plug   
    def create(self, name): 
     self.probe.create(name) 

    @_with_plug 
    def delete(self, name): 
     self.probe.delete(name) 

但是这种策略是行不通的。我怎么可以在类中使用方法来修饰其他方法来在调用方法之前和之后执行此类操作?

+0

什么是“但这种策略是行不通的。”意思? – Carcigenicate

+0

看起来像使用方法作为装饰器 - 以代码显示 - 总是给出错误,说明参数的数量。我认为这是我使用装饰者的方式不正确。 –

回答

0

您应该在类体外定义装饰器函数,并且装饰器函数应该返回包装函数以使其工作。例如:

def _with_plug(fn): 
    def wrapper(self, *args, **kwargs): 
     self.probe = self.connection.plug() 
     fn(self, *args, **kwargs) 
     self.probe.unplug() 
    return wrapper 


class Queue(object): 
    def __init__(self): 
     self.connection = Connection() 

    @_with_plug   
    def create(self, name): 
     self.probe.create(name) 

    @_with_plug 
    def delete(self, name): 
     self.probe.delete(name) 
1

好像有点糊涂参数对我说:

文件deco.py,说

def _with_plug(fn): # decorator takes exactly one argument, the function to wrap 
    print("wrapping", fn.__name__) 
    def wrapper(self, *args, **kwds): 
     print("wrapper called") 
     self.probe = [self.connection, ".plug()"] 
     fn(self, *args, **kwds) 
     self.probe.append(".unplug()") 
    return wrapper # decorator must return the wrapped function 


class Queue(object): 
    def __init__(self): 
     self.connection = "Connection()" 

    @_with_plug 
    def create(self, name): 
     self.probe.append("create(name)") 

    @_with_plug 
    def delete(self, name): 
     self.probe.append("delete(name)") 

检查:

>>> import deco 
wrapping create 
wrapping delete 
>>> q = deco.Queue() 
>>> q.create("name") 
wrapper called 
>>> q.probe 
['Connection()', '.plug()', 'create(name)', '.unplug()'] 

观察该装饰功能被称为在定义待包装函数的时间,即在类定义完成之前,并且在创建第一个实例之前很久。因此,您不能以您尝试的方式引用self