让我解释为什么我需要这样做:
我正在开发一个库,并且需要序列化python函数。
这是我使用的2个实用程序功能:
def serialize_func(fn: function) -> Tuple[bytes, str]:
return marshal.dumps(fn.__code__), fn.__name__
def deserialize_func(serialized_fn: Tuple[bytes, str]) -> function:
return types.FunctionType(
marshal.loads(serialized_fn[0]), globals(), serialized_fn[1]
)
现在,如果可以通过某种方式缓存序列化的函数,并将其存储在dict
中,如下所示:
Dict[function_hash, function]
{
<function hash>: <function>,
<function hash>: <function>,
...
}
由于我不需要重复序列化(和传输)它们,因此可以大大提高性能。
是否有可靠的方法来实现这一目标?
编辑:如果我尝试对函数进行哈希处理,那不完全是我的初衷。
In [1]: def x():
...: pass
In [2]: hash(x)
Out[2]: 8745212393041
In [3]: def x():
...: pass
In [4]: hash(x)
Out[4]: -9223363291642382793
我需要2个具有相同主体,签名,全局范围(以及其他一些我可能缺少的功能)的函数来返回相同的哈希值。
Here是有问题的图书馆。
编辑:这是我为什么要这样做的一些深入解释。
我正在将该功能从一个进程(“客户端”)发送到另一个(“服务器”),并在“服务器”上执行。
声音怪异而复杂,但是我有充分的理由。
整个过程使该功能在所有“客户端”上严格地原子化
“服务器”是“演员”。因此,一次只能运行一个功能,从而使程序员可以更轻松地避免出现竞争状况。
现在,如果“客户端”已经将函数发送到“服务器”一次,那么对于随后的交互,它仅发送该函数的哈希,“服务器”可以在其中查找该函数。它的桌子。
答案 0 :(得分:1)
我需要2个具有相同主体,签名,全局范围(以及其他一些我可能缺少的功能)的函数来返回相同的哈希值。
然后,您将必须根据这些条件自己构建哈希。
例如:
compute
请注意,第一个相同,因为代码和位置参数的数量相同-我们未包含static List<DataModel> createDataList(String responFroJson) {
,因此使用不同的字符串并将build
更改为{{ 1}}未考虑在内。请注意,最后一个是不同的,因为我们更改了操作(影响了def foo(x):
return "It is " + str(x + 1)
def bar(x):
return "The answer is " + str(x + 2)
def quux(x):
return "The answer is " + str(x - 2)
def fnhash(f):
c = f.__code__
return hash((c.co_argcount, c.co_code))
fnhash(foo)
# => -640999299468968616
fnhash(bar)
# => -640999299468968616
fnhash(quux)
# => -1235803056671018747
,又影响了co_consts
)。
完全由您决定要选择的代码对象的哪些属性才有意义(例如,我怀疑您想包含1
和2
)。请参见in the inspect
docs各个co_code
字段的含义。