python - 通过使其重新加载另一个函数来腌制一个用于多处理的函数
问题描述
假设我有以下简单的类:
class HelloWorld:
def call(self):
print('Hello World!')
然后我可以使用HelloWorld.call
with multiprocessing 虽然 python 知道如何 pickle HelloWorld.call
。但是,假设我想将该函数包装在一个元类中,
class MetaClass(type):
def __new__(mcs, name, bases, dct):
def wrap(f):
def wrapper(self):
print(f.__qualname__)
f(self)
return wrapper
new_dct = dict()
for attr_name in dct.keys():
if callable(dct[attr_name]):
new_dct[attr_name] = wrap(dct[attr_name])
else:
new_dct[attr_name] = dct[attr_name]
return type.__new__(mcs, name, bases, new_dct)
class HelloWorld(metaclass=MetaClass):
def call(self):
print('Hello World!')
然后我不能使用HelloWorld.call
多处理,因为它不会腌制。我想要的是使python不使用包装函数进行酸洗,而是使用原始函数(尽管在取消酸洗后它将默认引用包装函数)。
有什么建议么?谢谢!
解决方案
查看源代码,您可以看到ForkingPickler
( multiprocessing
's custom Pickler
) 通过方法__func__
-attribute's腌制__name__
。所以我要做的就是设置wrapper.__name__
与原始成员的名称相同:
class MetaClass(type):
def __new__(mcs, name, bases, dct):
def wrap(f):
def wrapper(self):
print(f.__qualname__)
f(self)
#############################
wrapper.__name__ = f.__name__
#############################
return wrapper
new_dct = dict()
for attr_name in dct.keys():
if callable(dct[attr_name]):
new_dct[attr_name] = wrap(dct[attr_name])
else:
new_dct[attr_name] = dct[attr_name]
return type.__new__(mcs, name, bases, new_dct)
class HelloWorld(metaclass=MetaClass):
def call(self):
print('Hello World!')
也可以使用functools.update_wrapper(wrapper, f)
而不仅仅是设置__name__
。也会起作用。
推荐阅读
- angular - 让父动画等待子动画在 Angular 中完成
- javascript - 将 onClick 按钮元素反应为 javascript 节点
- html - 试图在一个 div 中居中一个 div
- qml - 将 MouseArea 事件从父级传播到子级
- node.js - 从 node/express 对文件调用 OS 命令
- amazon-web-services - Amazon Elastic Beanstalk ebextension 将 nginx 配置参数添加到默认配置中
- vue.js - 选择下一个/上一个项目并将其放在织物 js 的前面
- terraform - 使用 terraform.workspace 选项时,Terraform 插值抛出错误
- spring - 如何保护 Spring Security 中受 IP 地址限制的匿名访问?
- c# - Amazon S3 存储桶 C# API 未捕获错误