gpt4 book ai didi

python - pickle 包装的部分功能

转载 作者:太空狗 更新时间:2023-10-29 23:55:11 26 4
gpt4 key购买 nike

我正在尝试使用部分函数创建一个可 pickle 的装饰器。但是,我在尝试这样做时不断遇到 pickling 错误。

第一个简单的例子如下:

def decorator(func):
def wrapper(**kwargs):
return partial(func, **kwargs)
return wrapper

@decorator
def decorated(x, y=1, z=2):
return x+y+z

y5 = decorated(y=5)
pickle.dumps(y5)

partial 取自 functools

不那么幼稚的尝试包括在 def wrapper 上方添加 @wraps 一行。这没有帮助。

我不确定我是否了解 pickling 的真正工作原理。

最佳答案

问题出在你的装饰器上,而不是partial。一个部分对象应该很好地 pickle :

>>> from pickle import *
>>> from functools import *
>>> f = partial(pow, 2)
>>> p = dumps(f)
>>> g = loads(p)
>>> g(5)
32

因此,您的代码的这个问题出在装饰器中。它不保留原始函数的名称。试试这个:

import pickle
from functools import *

def decorator(func):
def wrapper(**kwargs):
return partial(func, **kwargs)
return wrapper

def decorated(x, y=1, z=2):
return x+y+z

dd = decorator(decorated)

y5 = dd(y=5)
pickle.dumps(y5)

使用 dd 的修改应该允许 pickle 逻辑通过其名称发现底层函数。这就是 pickle 的工作原理。

要查看 pickle 中的函数名称,请查看 dumps 输出:

>>> print pickle.dumps(y5)
cfunctools
partial
p0
(c__main__
decorated
p1
tp2
Rp3
(g1
(t(dp4
S'y'
p5
I5
sNtp6
b.

“装饰”这个词需要是可发现的,等于底层功能,并且不被装饰器隐藏。请记住,当函数被 pickle 时,只会存储它们的名称。函数的实际内容不在 pickle 中。

有一些解决方法,但它们并不完美。您可以使用 __setstate__() 来保存函数名称及其源代码。然后添加一个 __getstate__() 方法以通过执行其源代码来恢复函数。

或者,您可以提取函数对象对象中的字节代码并保存它们。恢复后,编译代码对象并执行它。

简而言之,您使用带有 @ 符号的装饰器的目标与函数 pickling 的工作方式直接不一致。为了实现您的目标,您必须自定义函数 pickling 以保存函数的作用,而不仅仅是它的名称。

关于python - pickle 包装的部分功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14550577/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com