- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是我使用的代码
import funcy
@funcy.memoize
class mystery(object):
def __init__(self, num):
self.num = num
feat = mystery(1)
with open('num.pickle', 'wb') as f:
pickle.dump(feat,f)
这给了我以下错误:
PicklingError: Can't pickle <class '__main__.mystery'>: it's not the
same object as __main__.mystery
我希望 1) 理解为什么会发生这种情况,以及 2) 找到一个允许我腌制对象的解决方案(无需删除内存)。理想情况下,解决方案不会更改对 pickle 的调用。
使用 funcy==1.10 运行 python 3.6
最佳答案
问题是您已将为函数设计的装饰器应用到类中。结果不是一个类,而是一个封装了对该类的调用的函数。这会导致许多问题(例如,正如 Aran-Fey 在评论中指出的那样,您不能 isinstance(feat, mystery)
,因为 mystery
)。
但是您特别关心的问题是您不能 pickle 不可访问类的实例。
事实上,这基本上就是错误消息告诉您的内容:
PicklingError: Can't pickle <class '__main__.mystery'>: it's not the
same object as __main__.mystery
你的 feat
认为它的类型是 __main__.mystery
,但这根本不是一个类型,它是包装该类型的装饰器返回的函数。
解决这个问题的简单方法是找到一个类装饰器来做你想做的事。它可能被称为 flyweight
而不是 memoize
,但我确信存在大量示例。
但是您可以通过仅内存构造函数而不是内存类来构建享元类:
class mystery:
@funcy.memoize
def __new__(cls, num):
return super().__new__(cls)
def __init__(self, num):
self.num = num
... 尽管在这种情况下您可能希望将初始化移动到构造函数中。否则,调用 mystery(1)
然后 mystery(1)
将返回与以前相同的对象,但也会用 self.num = 1
重新初始化它,充其量是浪费,最坏的情况是不正确。所以:
class mystery:
@funcy.memoize
def __new__(cls, num):
self = super().__new__(cls)
self.num = num
return self
现在:
>>> feat = mystery(1)
>>> feat
<__main__.mystery at 0x10eeb1278>
>>> mystery(2)
<__main__.mystery at 0x10eeb2c18>
>>> mystery(1)
<__main__.mystery at 0x10eeb1278>
而且,因为 feat
的类型现在是一个可以在模块全局名称下访问的类 mystery
, pickle
完全没有问题:
>>> pickle.dumps(feat)
b'\x80\x03c__main__\nmystery\nq\x00)\x81q\x01}q\x02X\x03\x00\x00\x00numq\x03K\x01sb.'
您确实仍然想考虑这门课应该如何玩 pickling。特别是,您是否希望 unpickling 通过缓存?默认情况下,它不会:
>>> pickle.loads(pickle.dumps(feat)) is feat
False
发生的事情是它使用默认的 __reduce_ex__
对于酸洗,默认情况下相当于(只是稍微过于简化):
result = object.__new__(__main__.mystery)
result.__dict__.update({'num': 1})
如果你想让它通过缓存,最简单的解决方案是这样的:
class mystery:
@funcy.memoize
def __new__(cls, num):
self = super().__new__(cls)
self.num = num
return self
def __reduce__(self):
return (type(self), (self.num,))
如果您打算经常这样做,您可能会考虑编写自己的类装饰器:
def memoclass(cls):
@funcy.memoize
def __new__(cls, *args, **kwargs):
return super(cls, cls).__new__(cls)
cls.__new__ = __new__
return cls
但是这个:
__init__
的类(或者,至少,具有幂等且快速的 __init__
,重复调用无害),所以,我认为你最好不要直截了当,只记住 __new__
方法,或者写(或发现)一些更奇特的东西来进行内省(introspection),使以这种方式内存一个类完全通用。 (或者,或者,也许写一个只适用于一些受限制的类集的一个 - 例如,一个 @memodataclass
就像 @dataclass
但使用内存构造函数会比完全通用的 @memoclass
容易得多。)
关于python - 不能 Pickle memoize 类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51831733/
假设我有一个 A 类和一个派生自 A 的 B 类。我想 pickle/unpickle B 类的一个实例。A 和 B 都定义了 __getstate__/__setstate__ 方法(假设 A
似乎有两种方法可以将指标推向 Graphite /碳, 线路接收器 pickle 接收器 根据文档 http://graphite.readthedocs.org/en/1.0/feeding-car
Perforce命令行有一个特殊的开关-G,它使用python的“pickle”序列化格式可以使输出成为机器可读的。一般来说,实际上是这样吗? 例如,考虑p4 -G diff -duw3 的输出。
如何从 BytesIO 对象写入和读回 pickled 数据? 我尝试过: import io import cPickle as pickle s1 = "foo" bytes_io = io.By
我有两个文件: x.py class BF(object) def __init__(): . . def add(self,z): . . y.py from y
在 post昨天发帖,无意中发现改了__qualname__函数对 pickle 有意想不到的影响.通过运行更多测试,我发现在对函数进行 pickle 时,pickle不像我想的那样工作,改变 __q
为什么 pickle 重用现有的 Python 类“C”而不是从 pickle 字节重建类?有没有一种方法可以在没有副作用的情况下 pickle 和解 pickle ? 这是我的回复 session
我使用 mpi4py 将一些计算拆分到多个过程中。基本上我只是计算一些凸包的体积,这是我使用 tvtk 和 mayavi 创建的。 只有第一个过程导入这些库: ... if rank==0: f
我正在用 pygame 制作一个绘图程序,我想在其中为用户提供一个选项来保存程序的确切状态,然后在稍后重新加载它。在这一点上,我保存了我的全局字典的副本,然后遍历, pickle 每个对象。 pyga
所以,我有一个对象,里面有很多不可 pickle 的东西(pygame 事件、orderedDicts、时钟等),我需要将它保存到磁盘。 事情是,如果我可以让这个东西存储一个有进度的字符串(我只需要一
import pickle variety = ["sweet", "box", "cat"] shape = ["back","spear", "log"] pickleFile = open("
我有一个关于 gensim 的问题。我想知道在保存或加载模型(或多个模型)时是否建议或需要使用 pickle,因为我在 GitHub 上找到了可以使用的脚本。 mymodel = Doc2Vec(do
我正在使用 python3.6/。我使用 protocol=pickle.HIGHEST_PROTOCOL pickle 了我的文件 当我按如下方式加载时: with open('data.sav',
给定一个像这样的任意Pythonic对象: class ExampleObj(object): def __init__(self): self.a = 'a'
简介 我有一本具有以下格式的字典: dict_list = {'S0':[[list of int],[list of int]], 'S1':[[list of int],[list of int]
我想知道这个错误可能意味着什么: PicklingError: Can't pickle : attribute lookup __builtin__.function failed 我理解这与使用多
我对 python 变量持久性有点困惑,在我的代码中,我使用以下代码使模型参数在某些迭代期间持久化 with open('W_Hs_Hu_iter'+str(inx)+'.pickle', 'wb'
当对象通过其属性之一引用自身时,从带有插槽的类中挑选对象的正确方法是什么?这是一个简单的示例,使用我当前的实现,我不确定它是否 100% 正确: import weakref import pickl
我有数千个长 (8640) 整数列表元组。例如: type(l1) tuple len(l1) 2 l1[0][:10] [0, 31, 23, 0, 0, 0, 0, 0, 0, 0] l1[1][
我有一个对象 gui_project,它有一个属性 .namespace,这是一个命名空间字典。 (即从字符串到对象的字典。) (这在类似 IDE 的程序中使用,让用户在 Python shell 中
我是一名优秀的程序员,十分优秀!