这是我使用的代码
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)
这给了我以下错误:
^{pr2}$我希望1)理解为什么会发生这种情况,2)找到一个解决方案,让我可以对对象进行pickle处理(不删除记忆)。理想情况下,解决方案不会将调用更改为pickle。在
运行functy==1.10的python3.6
另一种方法是
问题是您已经将为函数设计的decorator应用到类中。结果不是一个类,而是一个结束对类的调用的函数。这会导致很多问题(例如,正如aranfey在评论中指出的,你不能
isinstance(feat, mystery)
,因为mystery
)。在但您关心的特别问题是不能pickle不可访问类的实例。在
实际上,这基本上就是错误消息告诉你的:
你的
feat
认为它的类型是__main__.mystery
,但那根本不是一个类型,而是由修饰符返回的函数包装了该类型。在解决这个问题的简单方法是找到一个类decorator,它可以满足您的需要。它可能被称为
flyweight
而不是memoize
,但我相信有很多例子存在。在但是,您可以通过记住构造函数而不是记住类来构建flyweight类:
^{pr2}$…虽然在这种情况下,您可能希望将初始化移到构造函数中。否则,调用
mystery(1)
,然后调用mystery(1)
将返回与之前相同的对象,但也会使用self.num = 1
重新初始化它,这充其量是浪费,最坏的情况是不正确的。所以:现在:
而且,由于
feat
的类型现在是一个可以在模块全局名称mystery
下访问的类,pickle
将不会有任何问题:你还想想想这门课应该怎么学酸洗。特别是,您是否希望unpickling遍历缓存?默认情况下,它不会:
{这只相当于使用默认值的^来做什么
如果您希望它通过缓存,最简单的解决方案是:
^{8}$如果您打算经常这样做,您可能会考虑编写自己的类装饰器:
但是这个:
__init__
(或者至少,具有幂等且快速的__init__
的类,重复调用是无害的)所以,我认为你最好是明确地记住
__new__
方法,或者编写(或找到)一些更为精巧的东西,来进行必要的内省,从而使以这种方式记类变得完全通用。(或者,也可以编写一个只适用于某些受限类集的程序,例如,@memodataclass
与@dataclass
类似,但是使用一个记忆化的构造函数要比完全通用的@memoclass
简单得多。)相关问题 更多 >
编程相关推荐