python - 在运行时装饰类方法
问题描述
我想装饰一个类方法,但是在运行时(我的意思是装饰器不需要在带有@符号的方法之前指定)
请参阅标准方法装饰器的此示例:
def method_decorator(func):
def decorated(self, *args, **kwargs):
print('decorator:', args, kwargs)
return func(self,*args, **kwargs)
return decorated
class Standard():
@ method_decorator
def decorated(self, *args, **kwargs):
print('decorated: ', args, 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):
setattr(self, 'decorated', decorator(self.decorated))
def decorated(self, *args, **kwargs):
print('decorated: ', args, kwargs)
r = RunTime()
r.set_decorator_*(method_decorator)
r.decorated(1,2)
以下是输出:
- 装饰器没有正确装饰:
decorator: (2,) {}
decorated: (1, 2) {}
- 按预期工作,但是当调用 set_decorator 时,所有的 RunTime 实例也都被装饰了,我想避免这种情况,因为我只想装饰单个实例的方法。
- 装修不好
decorator: (2,) {}
decorated: (2,) {}
- 与 3 相同
- 与 1 相同
我还尝试了另一个装饰器,它运行良好(使用 set_decorator_1)但不允许我在其中访问 self:
def method_decorator_runtime(func):
def decorated( *args, **kwargs):
print('decorator: ', args, 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), args, kwargs)
r = RunTime()
r.set_decorator(method_decorator)
r.decorated(1, 2)
推荐阅读
- angular - Angular 7.3.9 - 在应用程序 cookie 中找不到 JSESSIONID
- sql - 如何使用上一列中的值插入日期
- python - 为什么我们将 nn.Module 作为参数传递给神经网络的类定义?
- javascript - 大端格式到十进制转换
- javascript - 使用 ReactJS 上传旋转图像预览
- r - 如何将模型系数乘以一个数字?
- json - Chrome 和 Firefox 扩展:在哪里存储数据?
- sql - 如何在 ASP.NET MVC 和 SQL Server 中修复“对象在 Null 时应具有值”
- reactjs - 当我在visualstudio代码中保存js文档时创建空间
- hadoop - 无法使用 Java 代码连接到 Hive