如何通过cloudpickle来pickle python attrs类函数?

如何通过cloudpickle来pickle python attrs类函数?,python,pickle,python-3.7,python-attrs,Python,Pickle,Python 3.7,Python Attrs,我使用cloudpickle传递函数,我想通过cloudpickle传递一个attrs类函数 import pickle import attr @attr.s(auto_attribs=True) class myclass: an_int: int a_str: str a_float: float def myfunc(self): return f"{self.an_int} + {self.a_str} + {self.a_float

我使用cloudpickle传递函数,我想通过cloudpickle传递一个
attrs
类函数

import pickle
import attr

@attr.s(auto_attribs=True)
class myclass:
    an_int: int
    a_str: str
    a_float: float

    def myfunc(self):
        return f"{self.an_int} + {self.a_str} + {self.a_float}"

mc = myclass(1, "test", 2.4)
f = pickle.loads(pickle.dumps(mc.myfunc))
print(f())
运行此命令将为我提供
1+测试+2.4

而cloudpickle实现

import attr
import cloudpickle

@attr.s(auto_attribs=True)
class myclass:
    an_int: int
    a_str: str
    a_float: float

    def myfunc(self):
        return f"{self.an_int} + {self.a_str} + {self.a_float}"

mc = myclass(1, "test", 2.4)
f = cloudpickle.loads(cloudpickle.dumps(mc.myfunc))
print(f())
给我错误:
TypeError:can't pickle\u thread.\u local objects
(我将在底部发布完整的错误日志)

我相信我需要实现一些
\uu getstate\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

添加功能:

def __reduce__(self):
    return (self.__class__, (self.an_int, self.a_str, self.a_float))
给出了相同的错误

为了实现这一目标,我应该实施什么?

python错误日志:

Traceback (most recent call last):
  File "x.py", line 16, in <module>
    f = cloudpickle.loads(cloudpickle.dumps(mc.myfunc))
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 917, in dumps
    cp.dump(obj)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 268, in dump
    return Pickler.dump(self, obj)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 437, in dump
    self.save(obj)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 689, in save_instancemethod
    self.save_reduce(types.MethodType, (obj.__func__, obj.__self__), obj=obj)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 638, in save_reduce
    save(args)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 771, in save_tuple
    save(element)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 549, in save
    self.save_reduce(obj=obj, *rv)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 633, in save_reduce
    save(cls)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 664, in save_global
    return self.save_dynamic_class(obj)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 511, in save_dynamic_class
    save(clsdict)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 856, in save_dict
    self._batch_setitems(obj.items())
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 882, in _batch_setitems
    save(v)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 408, in save_function
    self.save_function_tuple(obj)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 573, in save_function_tuple
    save(state)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 856, in save_dict
    self._batch_setitems(obj.items())
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 882, in _batch_setitems
    save(v)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 856, in save_dict
    self._batch_setitems(obj.items())
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 882, in _batch_setitems
    save(v)
  File "/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py", line 524, in save
    rv = reduce(self.proto)
TypeError: can't pickle _thread._local objects
回溯(最近一次呼叫最后一次):
文件“x.py”,第16行,在
f=cloudpickle.load(cloudpickle.dumps(mc.myfunc))
转储文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site packages/cloudpickle/cloudpickle.py”,第917行
cp.dump(obj)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site packages/cloudpickle/cloudpickle.py”,第268行,在转储文件中
返回Pickler.dump(自、obj)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第437行,在转储文件中
自我保存(obj)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第504行,保存
f(self,obj)#用显式self调用未绑定方法
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site packages/cloudpickle/cloudpickle.py”,第689行,在save_instancemethod中
self.save\u reduce(types.MethodType,(obj.\uu func\uuuuuuuj,obj.\uuuuu self\uuuuuj),obj=obj)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第638行,保存
保存(args)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第504行,保存
f(self,obj)#用显式self调用未绑定方法
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第771行,在save_tuple中
保存(元素)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第549行,保存
自我保存(obj=obj,*rv)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第633行,在save_中
保存(cls)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第504行,保存
f(self,obj)#用显式self调用未绑定方法
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site packages/cloudpickle/cloudpickle.py”,第664行,在save_global中
返回self.save\u动态类(obj)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site packages/cloudpickle/cloudpickle.py”,第511行,在save_dynamic_类中
保存(clsdict)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第504行,保存
f(self,obj)#用显式self调用未绑定方法
保存目录中的文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第856行
self.\u batch\u setitems(obj.items())
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第882行,在批处理设置项中
保存(v)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第504行,保存
f(self,obj)#用显式self调用未绑定方法
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site packages/cloudpickle/cloudpickle.py”,第408行,在save_函数中
自我保存函数元组(obj)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/site packages/cloudpickle/cloudpickle.py”,第573行,在save_function_元组中
保存(状态)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第504行,保存
f(self,obj)#用显式self调用未绑定方法
保存目录中的文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第856行
self.\u batch\u setitems(obj.items())
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第882行,在批处理设置项中
保存(v)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第504行,保存
f(self,obj)#用显式self调用未绑定方法
保存目录中的文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第856行
self.\u batch\u setitems(obj.items())
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第882行,在批处理设置项中
保存(v)
文件“/home/me/.local/share/pyenv/versions/3.7.0/lib/python3.7/pickle.py”,第524行,保存
rv=减少(自编程)
TypeError:无法pickle\u线程。\u本地对象

这是由于
attrs
\uuuu repr\uuu
中使用线程局部变量来分解对象周期,而cloudpickle不喜欢这样做。作为参考,它是在年引入的

您的快速修复方法是设置
@attr.s(repr=False)
,但请随时在我们的bug追踪器上打开一个问题,我们可以讨论如何继续