python - 如何在 __new__ 方法中使用 pickle 缓存对象?
问题描述
我想在__new__
方法中缓存一个对象,以便在构造新对象时可以加载缓存,但是现在以下代码将出现异常:
RecursionError: maximum recursion depth exceeded while calling a Python object
我不知道如何打破递归
import pickle
class Cache:
def __init__(self):
self.d = {}
def __setitem__(self, obj, val):
self.d[obj] = pickle.dumps(val)
def __getitem__(self, obj):
return pickle.loads(self.d[obj])
class Car:
cache = Cache()
def __reduce__(self):
return (self.__class__, (self.name,))
def __new__(cls, name):
try:
return cls.cache[name]
except KeyError:
return cls.new(name)
@classmethod
def new(cls, name):
car = object.__new__(cls)
car.init(name)
cls.cache[name] = car
return car
def init(self, name):
self.name = name
def __repr__(self):
return self.name
a = Car('audi')
b = Car('audi')
解决方案
试试。这可能会解决这个问题,但它可能不是正确的解决方案。如果有人有更好的想法,请随时发表评论。
只需删除该__reduce__
方法。
然后实施__getnewargs__
并__getnewargs_ex__
import pickle
class Cache:
def __init__(self):
self.d = {}
def __setitem__(self, obj, val):
self.d[obj] = pickle.dumps(val)
def __getitem__(self, obj):
return pickle.loads(self.d[obj])
def __contains__(self, x):
return x in self.d
class Car:
cache = Cache()
def __new__(cls, name, extra=None, _FORCE_CREATE=False):
if _FORCE_CREATE or name not in cls.cache:
car = object.__new__(cls)
car.init(name)
car.extra = extra
cls.cache[name] = car
return car
else:
return cls.cache[name]
def init(self, name):
self.name = name
def __repr__(self):
return self.name
def __getnewargs__(self):
return (self.name, None, True)
def __getnewargs_ex__(self):
# override __getnewargs_ex__ and __getnewargs__ to provide args for __new__
return (self.name, ), {"_FORCE_CREATE": True}
a = Car('audi', extra="extra_attr")
b = Car('audi')
print(id(a), a.extra) # 1921399938016 extra_attr
print(id(b), b.extra) # 1921399937728 extra_attr
推荐阅读
- typescript - 从 React Native 过渡到 Flutter 时最重要的方面
- java - 如何在 javafx 多文件选择器中维护选定文件的顺序
- vue.js - v-treeview展开折叠实现
- r - 在 R 中解释夏皮罗威尔克测试
- c# - Fluent Validation 从不适用于任何条件 MVC 5
- curl - 使用 cygwin 和 curl 使用 crontab 将文件上传到 ftp
- ios - Xcode11:无法安装“AppName”
- python - 如何改进这个预测给定数字是奇数还是偶数的 Keras 模型
- javascript - 如何在表单验证中显示角度模板中的元素?
- python - PySpark Column 获取连接为字符串的值