简体   繁体   English

如何通过cloudpickle腌制python-attrs类函数?

[英]How to pickle python-attrs class functions via cloudpickle?

I'm using cloudpickle to pass functions around, and I'd like to pass an attrs class function via cloudpickle.我正在使用 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())

running this gives me 1 + test + 2.4运行这给了我1 + test + 2.4

While the cloudpickle implementation而 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())

gives me the error: TypeError: can't pickle _thread._local objects (I'll post the full error log at the bottom)给了我错误: TypeError: can't pickle _thread._local objects (我将在底部发布完整的错误日志)

I am confident that I need to implement some __getstate__ or __reduce__ function to get cloudpickle to pickle the class, but I've tried both without any luck.我相信我需要实现一些__getstate____reduce__函数来让 cloudpickle 对类进行腌制,但我已经尝试过两者都没有任何运气。

adding the function:添加功能:

def __reduce__(self):
    return (self.__class__, (self.an_int, self.a_str, self.a_float))

gives the same error给出同样的错误

What should I be implementing in order to accomplish this?为了实现这一目标,我应该实施什么?

python error log:蟒蛇错误日志:

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

This is caused by attrs using thread locals for breaking up object cycles in __repr__ and cloudpickle not liking that.这是由于attrs使用线程__repr__来分解__repr__对象循环,而 cloudpickle 不喜欢这样。 For reference, it was introduced in https://github.com/python-attrs/attrs/pull/358 .作为参考,它是在https://github.com/python-attrs/attrs/pull/358中介绍的。

Your quick fix is to set @attr.s(repr=False) but feel free to open an issue on our bug tracker and we can discuss how to proceed.您的快速解决方法是设置@attr.s(repr=False)但随时在我们的错误跟踪器上打开一个问题,我们可以讨论如何继续。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM