通过重新加载另一个函数来选择多处理函数
Pickle a function for multiprocessing by making it reload another
假设我有以下简单的 class:
class HelloWorld:
def call(self):
print('Hello World!')
然后我可以将 HelloWorld.call
与多处理一起使用,尽管 python 知道如何 pickle HelloWorld.call
。但是,假设我想将该函数包装在 metaclass,
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
用于多处理,因为它不会 pickle。我想要的是 python 不使用包装函数进行 pickling,而是使用原始函数(尽管在 unpickling 之后它会默认引用包装函数)。
有什么建议吗?谢谢!
查看源码,可以看到ForkingPickler
(multiprocessing
的自定义Pickler
)通过__func__
-属性的[=15=方法pickles ].所以我要做的就是将 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__
。也可以。
假设我有以下简单的 class:
class HelloWorld:
def call(self):
print('Hello World!')
然后我可以将 HelloWorld.call
与多处理一起使用,尽管 python 知道如何 pickle HelloWorld.call
。但是,假设我想将该函数包装在 metaclass,
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
用于多处理,因为它不会 pickle。我想要的是 python 不使用包装函数进行 pickling,而是使用原始函数(尽管在 unpickling 之后它会默认引用包装函数)。
有什么建议吗?谢谢!
查看源码,可以看到ForkingPickler
(multiprocessing
的自定义Pickler
)通过__func__
-属性的[=15=方法pickles ].所以我要做的就是将 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__
。也可以。