- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
下面的最小示例使用了一个虚拟装饰器,它只是在构造装饰类的对象时打印一些消息。
import pickle
def decorate(message):
def call_decorator(func):
def wrapper(*args, **kwargs):
print(message)
return func(*args, **kwargs)
return wrapper
return call_decorator
@decorate('hi')
class Foo:
pass
foo = Foo()
dump = pickle.dumps(foo) # Fails already here.
foo = pickle.loads(dump)
然而,使用它会使 pickle
引发以下异常:
_pickle.PicklingError: Can't pickle <class '__main__.Foo'>: it's not the same object as __main__.Foo
我能做些什么来解决这个问题吗?
最佳答案
Pickle 要求实例的__class__
属性可以通过导入加载。
Pickling 实例仅存储实例数据,该类的 __qualname__
和 __module__
属性用于稍后通过再次导入该类来重新创建实例,并且为该类创建一个新实例。
Pickle 验证该类实际上可以首先导入。 __module__
和 __qualname__
对用于查找正确的模块,然后访问该模块上由 __qualname__
命名的对象,如果 __class__
对象和在模块上找到的对象不匹配,会引发您看到的错误。
这里,foo.__class__
指向一个 __qualname__
设置为 'Foo'
和 __module__
的类对象设置为 '__main__'
,但是 sys.modules['__main__'].Foo
不指向一个类,而是指向一个函数,包装器
装饰器返回的嵌套函数。
有两种可能的解决方案:
不要返回函数,返回原始类,并可能检测类对象来完成包装器所做的工作。如果您对类构造函数的参数进行操作,请在装饰类上添加或包装 __new__
或 __init__
方法。
考虑到 unpickling 通常在类上调用 __new__
来创建一个新的空实例,然后再恢复实例状态(除非 pickling 已经是 customised )。
将类存储在新位置。更改类的 __qualname__
和可能的 __module__
属性,以指向 pickle 可以找到原始类的位置。在 unpickling 上,将再次创建正确类型的实例,就像原始的 Foo()
调用一样。
另一种选择是为生成的类自定义 pickle 。你可以给类(class)new __reduce_ex__
和 new __reduce__
相反,指向包装函数或自定义 reduce 函数的方法。这可能会变得复杂,因为该类可能已经自定义了 pickling,并且 object.__reduce_ex__
提供了默认值,并且返回值可能因 pickle 版本而异。
如果你不想改变类,你也可以使用 copyreg.pickle()
function为该类注册自定义 __reduce__
处理程序。
无论哪种方式,reducer 的返回值仍应避免引用该类,而应引用新的构造函数,使用它可以导入的名称。如果您直接将装饰器与 new_name = decorator()(classobj)
一起使用,这可能会出现问题。 Pickle 本身也不会处理这种情况(因为 classobj.__name__
不会匹配 newname)
。
关于python - Pickle 和装饰类(PicklingError : not the same object),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52185507/
我在cmd中发起了焰火,并在下面进行了表演,以提高我的技能。。当我执行a.take(1)时,我得到“_ickle.PicklingError:无法序列化对象:IndexError:tuple inde
我有以下两个数据帧:df_whitelist和df_text +-------+--------------------+ |keyword| whitelist_terms | +------
执行示例 from multiprocessing import Process def f(name): print 'hello', name if __name__ == '__main
我正在做一个 Python/Django/Wagtail 项目,我有一些 api 可以返回一些分页的文章。它是这样的: 在网址中: url(r'^morearticles/', views.get_l
在多处理模块中使用 Pool.map_async()(以及 Pool.map())时遇到问题。我已经实现了一个并行循环函数,只要 Pool.map_async 的函数输入是“常规”函数,它就可以正常工
我在测试使用 mock 调用方法时遇到问题-- 作为一个简单的例子,假设方法是 os.getcwd .我想测试我自己的功能,pickle_wdir , 正在调用 os.getcwd如预期。但是,我正在
你知道解决这个问题的方法吗: [Thu Jul 08 19:15:38 2010] [error] [client 79.162.31.162] mod_wsgi (pid=3072): Except
下面的最小示例使用了一个虚拟装饰器,它只是在构造装饰类的对象时打印一些消息。 import pickle def decorate(message): def call_decorator(f
我有以下代码: def decorator(func): @functools.wraps(func) def other_func(): print('other f
尝试围绕执行 map_async() 的函数编写一些单元测试手术。更具体地说,我想确认在某个进程中发生异常时某些文件会被清理。下面提供了具有意图的示例伪代码。 foo.py def write_chu
我正在尝试编写一个基于 multiprocessing 的便捷函数库,它接受任何函数和参数,并使用多个进程运行该函数。我正在导入以下文件“MultiProcFunctions.py”: import
在没有修改的情况下运行 Elephas 示例时出错:(即使使用 git 版本 pip install --no-cache-dir git+git://github.com/maxpumperla/e
我正在尝试根据本教程的指导为 Python sklearn 管道创建自定义转换器:http://danielhnyk.cz/creating-your-own-estimator-scikit-lea
我想在给定目录中的所有图像中搜索冲浪,并保存它们的关键点和描述符以供将来使用。我决定使用pickle,如下所示: #!/usr/bin/env python import os import pick
很抱歉,我无法用更简单的示例重现该错误,并且我的代码太复杂而无法发布。如果我在 IPython shell 而不是常规的 Python 中运行程序,一切都会顺利进行。 我查阅了有关此问题的一些以前的注
我在 dataproc 上运行 pyspark 作业时遇到此错误。可能是什么原因 ? 这是错误的堆栈跟踪。 File "/usr/lib/python2.7/pickle.py", line 33
我希望使用 Celery/RabbitMQ 在 Windows 7 和 Python 3.3 上的 Flask 应用程序中运行常规间隔任务。 Pip 安装: billiard==3.3.0.10 ce
这个问题在这里已经有了答案: Can't pickle when using multiprocessing Pool.map() (14 个答案) 关闭 5 年前。 我正在尝试使用 python
当我尝试使用以下命令将表复制到 cassandra 时: copy images from 'images.csv' 我得到错误: 'PicklingError: Can't pickle : att
我从我的 GAE Python 应用程序中的这行代码中收到 PicklingError: deferred.defer(email_voters_begin, ekey, voter_list) 这三
我是一名优秀的程序员,十分优秀!