在类中包装不安全的python方法(例如os.chdir)如何使其线程/异常安全?
在这个问题中,公认的答案建议将os.chdir调用包装在一个类中,以确保返回到原始dir异常的安全性。以下是建议的代码:在类中包装不安全的python方法(例如os.chdir)如何使其线程/异常安全?,python,exception-handling,Python,Exception Handling,在这个问题中,公认的答案建议将os.chdir调用包装在一个类中,以确保返回到原始dir异常的安全性。以下是建议的代码: class Chdir: def __init__( self, newPath ): self.savedPath = os.getcwd() os.chdir(newPath) def __del__( self ): os.chdir( self.savedPath ) 有人能详细说明一下如何使不安全的调用异常安
class Chdir:
def __init__( self, newPath ):
self.savedPath = os.getcwd()
os.chdir(newPath)
def __del__( self ):
os.chdir( self.savedPath )
有人能详细说明一下如何使不安全的调用异常安全吗?
\uu del\uu
在实例即将销毁时调用。因此,当您实例化此类时,当前工作目录将保存到实例属性中,然后调用os.chdir。当实例被销毁时(无论出于何种原因),当前目录将更改为其旧值
这在我看来有点不正确。据我所知,您必须在覆盖的\uuuu del\uuu
中调用父级的\uu del\uuu
,因此它应该更像这样:
class Chdir(object):
def __init__(self, new_path):
self.saved_path = os.getcwd()
os.chdir(new_path)
def __del__(self):
os.chdir(self.saved_path)
super(Chdir, self).__del__()
当然,除非我遗漏了什么
(顺便问一下,您不能使用contextmanager执行同样的操作吗?此代码本身既不是线程安全的,也不是异常安全的。实际上,我不太确定你说的异常安全是什么意思。我想到了以下代码:
try:
# something thrilling
except:
pass
这是个糟糕的主意。例外情况并不是为了防范。写得好的代码应该是有用的。对这个问题的直接回答是:没有,发布的代码很糟糕 类似于以下的内容可以合理地使其“异常安全”(但更好的做法是避免chdir,而是使用完整路径):
这种精确的行为也可以写入到上下文管理器中 线程安全和异常安全实际上根本不是一回事。在这样的类中包装
os.chdir
调用是为了使其异常安全而不是线程安全
异常安全是你经常听到C++开发者谈论的话题。Python社区几乎没有这么多人谈论它。从Boost的文档中:
非正式地说,异常安全是指 组件意味着它显示 例外情况下的合理行为 在执行过程中抛出。对于 大多数人认为“合理”一词 包括所有通常的期望 对于错误处理:这需要资源 不应该泄露,而且 程序应保留在 定义良好的状态,以便执行 我们可以继续 因此,您提供的代码片段的想法是确保在出现异常的情况下,程序将返回到定义良好的状态。在这种情况下,无论os.chdir本身是否失败,或者是什么原因导致抛出异常并删除“chdir”实例,进程都将返回到它启动的目录中 这种使用仅为清理而存在的对象的模式是“”或“RAII”的一种形式。这种技术在C++中非常流行,但由于Python的原因,在以下方面不受欢迎:- Python有
…try
,它的作用几乎相同,是Python中更常见的习惯用法finally
- Python中的析构函数(
)在某些实现中是不可靠/不可预测的,因此以这种方式使用它们有些不受鼓励。在cpython中,只要不涉及周期(即:通过引用计数处理删除),它们就非常可靠和可预测,但在其他实现中(Jython和我相信IronPython),当垃圾收集器处理它时,删除就会发生,这可能要晚得多。(有趣的是,这并不能阻止大多数Python程序员依靠\uu del\uu
关闭打开的文件。)\uu del\uu
saved_path = os.getcwd()
os.chdir(new_path)
try:
# code that does stuff in new_path goes here
finally:
os.chdir(saved_path)
我认为“异常安全”的意思是:“即使由于引发异常而失去控制,我们也保证返回到原始目录”。有趣的是,你说它不是异常安全的,然后承认你不知道异常安全是什么意思。不管异常安全是什么意思;你能说“仅此代码是异常安全的”吗?我指的是问题中的Chdir类。Shylent-没错。这就是我通过“异常安全”得到的意思。最好使用with语句(Python 2.5+)
os.chdir(newPath)
可能不应该出现在try
语句中-如果失败,当前工作目录没有更改,因此不需要重置它。(在这种情况下,它是无害的,因为os.chdir(os.getcwd())
是一个no-op,但是如果saved\u path
是相对的,这将是一个问题)
saved_path = os.getcwd()
os.chdir(new_path)
try:
# code that does stuff in new_path goes here
finally:
os.chdir(saved_path)