python - 如何自动将数字特殊方法添加到类中?
问题描述
是否有可能以某种方式拦截Python 中类的数字魔法或 dunder 方法?适用于所有“__getattr__
正常”方法,但它不会拦截__add__
,__mul__
等方法。我认为这可能有一些元类?内置dataclass
包似乎有点接近我正在寻找的东西。
例如。我想创建一个类,它将拦截对、等的Number
所有方法调用。这似乎不起作用:__add__
__mul__
__truediv__
class Number(int):
def __repr__(self):
return "I am a number"
a = Number()
b = Number()
c = a + b # this will not preserve the subclass (Number)
我想要什么:
class Number(NumberMetaClass):
def __repr__(self):
return "I am a number"
def intercept_special_numeric(self, special_method, *args):
print("intercept")
return special_method(*args)
a = Number()
b = Number()
c = a + b # subclass is preserved and this will print "intercept"
或者也许只是:
class Number(NumberMetaClass):
def __repr__(self):
return "I am a number"
def __getattr_special__(self, dunder_attr):
print("intercept")
return getattr(Number, dunder_attr)
解决方案
所以如果我理解正确,你想从一个类型继承,也想拦截它的方法。我对吗?
您可以对元编程和元类做同样的事情。但我认为使用“类装饰器”要简单得多。这是我的方法:
from functools import wraps
def intercept_numeric_methods(cls):
def method_decorator(fn):
@wraps(fn)
def inner(*args, **kwargs):
print('Intercepted')
return fn(*args, **kwargs)
return inner
numeric_methods = {'__add__', '__mul__'}
for method_name, method in int.__dict__.items():
if method_name in numeric_methods:
setattr(cls, method_name, method_decorator(method))
return cls
@intercept_numeric_methods
class Myclass(int):
pass
obj1 = Myclass(10)
obj2 = Myclass(20)
print(obj1 + obj2)
我刚刚添加了__add__
和__mul__
。将您想要的方法的名称添加到numeric_methods
集合中。
推荐阅读
- java - ThreadLocal 为不同的线程返回相同的实例
- cefsharp - 潜在的 CEF 缓存损坏情况
- php - 试图从 Laravel 中的 MySQL 获取标记值
- java - Java Security 类可防止您使用 exit(0) 终止代码!在 HackerRank
- asp.net-mvc - 将 ASP.NET Core 2.2 迁移到 3.1 后,Reponse.cookies 无法正常工作
- batch-file - 使用批处理的带有密码和加密的 RAR 文件
- laravel - Laravel 7资源路径中的自动范围
- kubernetes - 远程写入和远程读取的 Prometheus 错误“服务器返回 HTTP 状态 401 未授权”
- c++ - 从 VS 2015 Update 3 更新到 VS2015 Update 3 d 后浮点计算行为不同的原因
- c++ - 在文件上实现迭代器