python中函数对象的哈希

时间:2018-08-24 06:23:46

标签: python

让我解释为什么我需要这样做:

我正在开发一个库,并且需要序列化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是有问题的图书馆。


编辑:这是我为什么要这样做的一些深入解释。

我正在将该功能从一个进程(“客户端”)发送到另一个(“服务器”),并在“服务器”上执行。

声音怪异而复杂,但是我有充分的理由。

整个过程使该功能在所有“客户端”上严格地原子化

“服务器”是“演员”。因此,一次只能运行一个功能,从而使程序员可以更轻松地避免出现竞争状况。

现在,如果“客户端”已经将函数发送到“服务器”一次,那么对于随后的交互,它仅发送该函数的哈希,“服务器”可以在其中查找该函数。它的桌子。

1 个答案:

答案 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)。

完全由您决定要选择的代码对象的哪些属性才有意义(例如,我怀疑您想包含12)。请参见in the inspect docs各个co_code字段的含义。