使用实例方法作为另一个类中的装饰器

Jor*_*Lee 7 python patch mocking instance python-decorators

我正在尝试创建一个MySerial实例化串行对象的类 ( ),以便我可以写入/读取串行设备 (UART)。有一个实例方法,它是一个装饰器,它包裹着属于完全不同的类 ( App)的函数。所以装饰器负责写入和读取串行缓冲区。

如果我MySerialApp类内部创建了一个实例,我就不能使用从MySerial. 我已经尝试了上述实例方法并使用类方法,如第二个答案中所述,但我确实需要实例化MySerial,从而使用__init__.

如何做到这一点?不可能吗?

  • 创建一个装饰器,它是一个实例方法。
  • 在另一个类中使用这个装饰器

class MySerial():
    def __init__(self):
        pass # I have to have an __init__
    def write(self):
        pass # write to buffer
    def read(self):
        pass # read to buffer
    def decorator(self, func):
        def func_wrap(*args, **kwargs):
            self.write(func(*args, **kwars))
            return self.read()
        return func_wrap

class App():
    def __init__(self):
        self.ser = MySerial()

    @self.ser.decorator  # <-- does not work here.
    def myfunc(self):
        # 'yummy_bytes' is written to the serial buffer via 
        # MySerial's decorator method
        return 'yummy_bytes'

if __name__ == '__main__':
    app = App()
Run Code Online (Sandbox Code Playgroud)

Aja*_*234 2

您可以使用 astaticmethod来换行decorator。的内部func_wrap函数decorator在其签名中包含一个附加参数:clscls可以用来访问ser实例的属性App,然后可以从 调用所需的方法write和。另请注意,在您的声明中,不接受任何参数,但传递了包装函数的结果。下面的代码用于防止否则会引发:readcls.serMySerial.write*argsTypeError

class MySerial():
   def __init__(self):
     pass # I have to have an __init__
   def write(self, *args):
     pass # write to buffer
   def read(self):
     pass # read to buffer
   @staticmethod
   def decorator(func):
     def func_wrap(cls, *args, **kwargs):
        cls.ser.write(func(cls, *args, **kwargs))
        return cls.ser.read()
     return func_wrap

class App():
  def __init__(self):
     self.ser = MySerial()
  @MySerial.decorator 
  def myfunc(self):
    # 'yummy_bytes' is written to the serial buffer via 
    # MySerial's decorator method
    return 'yummy_bytes'

App().myfunc()
Run Code Online (Sandbox Code Playgroud)