最近有人提出了一个问题,该问题涉及一些试图通过使用 pickled 进程来促进分布式计算的 Python 代码。显然,该功能在历史上是可行的,但出于安全原因,该功能已被禁用。在第二次尝试通过套接字传输函数对象时,仅传输了引用。如果我错了请纠正我,但我不认为这个问题与 Python 的后期绑定(bind)有关。假定不能 pickle 进程和线程对象,有没有办法传输可调用对象?我们希望避免为每个作业传输压缩的源代码,因为这可能会使整个尝试变得毫无意义。出于可移植性原因,只能使用 Python 核心库。
最佳答案
您可以编码字节码并 pickle 其他函数:
import marshal
import pickle
marshaled_bytecode = marshal.dumps(your_function.func_code)
# In this process, other function things are lost, so they have to be sent separated.
pickled_name = pickle.dumps(your_function.func_name)
pickled_arguments = pickle.dumps(your_function.func_defaults)
pickled_closure = pickle.dumps(your_function.func_closure)
# Send the marshaled bytecode and the other function things through a socket (they are byte strings).
send_through_a_socket((marshaled_bytecode, pickled_name, pickled_arguments, pickled_closure))
在另一个python程序中:
import marshal
import pickle
import types
# Receive the marshaled bytecode and the other function things.
marshaled_bytecode, pickled_name, pickled_arguments, pickled_closure = receive_from_a_socket()
your_function = types.FunctionType(marshal.loads(marshaled_bytecode), globals(), pickle.loads(pickled_name), pickle.loads(pickled_arguments), pickle.loads(pickled_closure))
并且函数内部对全局变量的任何引用都必须在接收函数的脚本中重新创建。
在 Python 3 中,使用的函数属性是 __code__
、__name__
、__defaults__
和 __closure__
。
请注意,send_through_a_socket
和 receive_from_a_socket
实际上并不存在,您应该将它们替换为通过套接字传输数据的实际代码。
关于python - 我们需要挑选任何类型的可调用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6234586/