我想用singleton模式编写一个类,使用pickle / dict提供一些持久的数据存储:
@singleton
class Pdb:
def __init__(self):
self.cache = None
self.dirty = False
try:
with open("data.pck","rb") as fp:
self.cache = pickle.load(fp)
except FileNotFoundError:
pass
except pickle.PickleError:
pass
if self.cache is None:
self.cache = {}
def flush(self):
if self.dirty:
try:
with open("data.pck","wb") as fp:
pickle.dump(self.cache,fp,protocol=4)
except pickle.PickleError:
pass
else:
self.dirty = False
def __del__(self): # PROBLEM HERE
self.flush()
当我使用python 2时,我可以通过覆盖__del__来实现。但它在python 3中似乎不正确。我该怎么办?
如果我用"用"声明,我需要将实例传递给我调用的每个函数:
def func1(db):
db.set(...)
func3(db,x1,x2,...)
with Pdb() as db:
func1(db)
func2(db)
这很复杂。是否有一种pythonic方式来实现全球范围"与"声明?
答案 0 :(得分:1)
不,你不是。只需使用你的单身人士:如果我用"用"声明,我需要将实例传递给我调用的每个函数:
# global
db = Pdb()
# any other context
with db:
所需要的只是表达式生成一个上下文管理器。使用__enter__
和__exit__
方法引用单个对象将满足该要求。您甚至可以忽略__enter__
返回值,就像我上面所做的那样。全局仍可用于您的所有功能,唯一可以改变的是__enter__
和__exit__
将在适当的位置调用。
请注意,即使在Python 2中,您也应该不依赖于__del__
被调用。在CPython实现中,在循环引用之外,调用__del__
时的规则在Python 2和3之间没有变化。