python3 带有 "with" 语句的单例模式
python3 singleton pattern with "with" statement
我想用单例模式写一个 class 来提供一些使用 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.我该怎么做?
如果我通过 "with" 语句执行此操作,我将需要将实例传递给我调用的每个函数:
def func1(db):
db.set(...)
func3(db,x1,x2,...)
with Pdb() as db:
func1(db)
func2(db)
这很复杂。是否有 pythonic 方法来执行全局范围 "with" 语句?
If I do it by "with" statement, I will need to pass the instance to each function that I call:
不,你不知道。只需使用您的单例:
# global
db = Pdb()
# any other context
with db:
所需要的只是表达式生成上下文管理器。使用 __enter__
和 __exit__
方法引用单例对象将满足该要求。您甚至可以像我上面那样忽略 __enter__
return 值。全局仍可用于您的所有函数,唯一改变的是 __enter__
和 __exit__
将在适当的位置调用。
请注意,即使在 Python 2 中,您也应该 而不是 依赖 __del__
被调用。在 CPython 实现中,在循环引用之外,调用 __del__
的规则在 Python 2 和 3 之间没有改变。
我想用单例模式写一个 class 来提供一些使用 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.我该怎么做?
如果我通过 "with" 语句执行此操作,我将需要将实例传递给我调用的每个函数:
def func1(db):
db.set(...)
func3(db,x1,x2,...)
with Pdb() as db:
func1(db)
func2(db)
这很复杂。是否有 pythonic 方法来执行全局范围 "with" 语句?
If I do it by "with" statement, I will need to pass the instance to each function that I call:
不,你不知道。只需使用您的单例:
# global
db = Pdb()
# any other context
with db:
所需要的只是表达式生成上下文管理器。使用 __enter__
和 __exit__
方法引用单例对象将满足该要求。您甚至可以像我上面那样忽略 __enter__
return 值。全局仍可用于您的所有函数,唯一改变的是 __enter__
和 __exit__
将在适当的位置调用。
请注意,即使在 Python 2 中,您也应该 而不是 依赖 __del__
被调用。在 CPython 实现中,在循环引用之外,调用 __del__
的规则在 Python 2 和 3 之间没有改变。