微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

运行时装饰类方法

如何解决运行时装饰类方法

我想装饰一个方法,但是在运行时(我的意思是不需要在方法之前用@ 符号指定装饰器)

请参阅此标准方法装饰器示例:

def method_decorator(func):
    def decorated(self,*args,**kwargs):
        print('decorator:',args,kwargs)
        return func(self,**kwargs)
    return decorated

class Standard():
    @ method_decorator
    def decorated(self,**kwargs):
        print('decorated: ',kwargs)

s = Standard()
s.decorated(1,2)

结果:

decorator: (1,2) {}
decorated:  (1,2) {}

所以我在运行时尝试了不同的方法

class RunTime():
    def set_decorator_1(self,decorator):
        self.decorated = decorator(self.decorated)
    def set_decorator_2(self,decorator):
        RunTime.decorated = decorator(RunTime.decorated)
    def set_decorator_3(self,decorator):
        self.decorated = decorator(RunTime.decorated)
    def set_decorator_4(self,decorator):
        setattr(self,'decorated',decorator(RunTime.decorated))
    def set_decorator_5(self,decorator(self.decorated))
    def decorated(self,kwargs)

r = RunTime()
r.set_decorator_*(method_decorator)
r.decorated(1,2)

这里是输出

  1. 装饰器没有正确装饰:
decorator: (2,) {}
decorated:  (1,2) {}
  1. 按预期工作,但是当 set_decorator 被调用时,所有 RunTime 实例也会被装饰,我想避免这种情况,因为我只想装饰单个实例的方法
  2. 糟糕的装饰
decorator: (2,) {}
decorated:  (2,) {}
  1. 同3
  2. 同1

我还尝试了另一个装饰器,它运行良好(使用 set_decorator_1)但不允许我在其中访问 self:

def method_decorator_runtime(func):
    def decorated( *args,**kwargs):
        print('decorator: ',kwargs)
        return func( *args,**kwargs)
    return decorated

有谁知道在运行时装饰方法的正确方法,能够在装饰器中访问 self 吗?

解决方法

我为您的问题找到的最接近的解决方案是使用带有参数的装饰器,您可以在其中传递装饰其方法的对象的实例。

def method_decorator(self_eventually):
    def decorator(func):
        def decorated(*args,**kwargs):
            print('decorator:',repr(self_eventually),args,kwargs)
            return func(*args,**kwargs)
        return decorated
    return decorator

class RunTime():

    def set_decorator(self,decorator):
        self.decorated = decorator(self)(self.decorated)

    def decorated(self,*args,**kwargs):
        print('decorated:',repr(self),kwargs)

r = RunTime()
r.set_decorator(method_decorator)
r.decorated(1,2)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。