gpt4 book ai didi

python - 如何将 `lambda` 对象转换为 `function` 对象以在 Python 中进行酸洗?

转载 作者:行者123 更新时间:2023-12-03 17:16:41 26 4
gpt4 key购买 nike

我一直在处理有关 lambda 的错误功能及其无法成为pickled .我经常用lambda当我必须单独以函数形式重新创建简单的 lambda 函数以用于酸洗时,它会大大降低我的工作流程效率。

有没有办法转换 lambda并将其所有参数放入 function Python 3.6.1 中的对象?

lambda_func = lambda x: x.split(" ")
def func(x):
return x.split(" ")
input_string = "Darth Plagueis was a Dark Lord of the Sith"

# Function Version
func(input_string)
# ['Darth', 'Plagueis', 'was', 'a', 'Dark', 'Lord', 'of', 'the', 'Sith']
lambda_func(input_string)
# ['Darth', 'Plagueis', 'was', 'a', 'Dark', 'Lord', 'of', 'the', 'Sith']

def lambda2func(lambda_func):
#...
return func_version

最佳答案

pickle不保存代码对象,只保存它的名称。然而,给一个函数起一个名字并不足以让它变得可腌制,因为 unpickle通过导入名称反序列化它。自然,这意味着它必须可以被 unpickling 运行时导入。功能 def由于这个原因,带有名称的 ed 仍然无法腌制。因此,即使您可以将 lambda 转换为命名函数,这仍然行不通:

>>> import pickle
>>> def foo():
... def bar():
... pass
... return bar
...
>>> pickle.dumps(foo())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Can't pickle local object 'foo.<locals>.bar'

你说出你不使用 dill 的原因相反是

I've seen a use case where dill can be imported as pickle which is pretty cool but gets confusing in the code since I used pickle and dill for different types of serialization.



但是 pickle序列化格式可扩展为您喜欢的任何内部格式 — json , gzip , 甚至 dill .你可以吃蛋糕也可以吃!

让我们试试 dill ,因为这很容易:
import pickle
import dill

class DillPickle:
def __init__(self, e):
self.e = e
def __getstate__(self):
return dill.dumps(self.e)
def __setstate__(self, state):
self.e = dill.loads(state)

Pickle 通常通过递归地酸洗对象的 __dict__ 来序列化自定义类实例的状态。 .在 unpickling 时,它可以创建一个未初始化的实例并更新它的 __dict__与保存的值。如果它的所有内容都是可腌制的,那么这是可行的。但如果不是,(如 lambdas 的情况)酸洗会失败。但是 pickle模块提供了一个接口(interface)来覆盖这个行为: __getstate__()用于序列化对象的状态,以及 __setstate__()从该值恢复它。如果返回值 __getstate__()是可腌制的(并且 __setstate__() 已实现),这是可行的。在这种情况下,我们返回 dill.dumps() 返回的可提取字节串。 .

示范:
>>> pickle.dumps(DillPickle(lambda x, y: x+y))
b'\x80\x03c__main__\nDillPickle\nq\x00)\x81q\x01C\xe7\x80\x03cdill._dill\n_create_function\nq\x00(cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04(K\x02K\x00K\x02K\x02KCC\x08|\x00|\x01\x17\x00S\x00q\x05N\x85q\x06)X\x01\x00\x00\x00xq\x07X\x01\x00\x00\x00yq\x08\x86q\tX\x1f\x00\x00\x00<ipython-input-18-48b9de2c6f55>q\nX\x08\x00\x00\x00<lambda>q\x0bK\x01C\x00q\x0c))tq\rRq\x0ec__builtin__\n__main__\nh\x0bNN}q\x0fNtq\x10Rq\x11.q\x02b.'
>>> pickle.loads(_).e('foo', 'bar')
'foobar'

请注意,我们使用 pickle 加载它,而不是 dill !并且 lambda 没有名称。当然, dill必须对运行时可用才能取消腌制,但 DillPickle 的其余部分也是如此类,就像任何用 pickle 序列化的自定义类型一样. dill现在只是 DillPickle 内部使用的实现细节.接口(interface)是 pickle .

你甚至可以让它成为可调用的,所以你不需要添加 .e你自己。
class DillPickleCallable(DillPickle):
def __call__(self, *args, **kwargs):
return self.e(*args, **kwargs)

关于python - 如何将 `lambda` 对象转换为 `function` 对象以在 Python 中进行酸洗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43899277/

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