<p>我建议使用Python的<code>with</code>语句来管理需要清理的资源。使用显式<code>close()</code>语句的问题是,您必须担心人们忘记调用它或忘记将它放在<code>finally</code>块中,以防止发生异常时发生资源泄漏。</p>
<p>要使用<code>with</code>语句,请使用以下方法创建类:</p>
<pre><code> def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
</code></pre>
<p>在上面的例子中,您将使用</p>
<pre><code>class Package:
def __init__(self):
self.files = []
def __enter__(self):
return self
# ...
def __exit__(self, exc_type, exc_value, traceback):
for file in self.files:
os.unlink(file)
</code></pre>
<p>然后,当有人想使用你的课程时,他们会做以下操作:</p>
<pre><code>with Package() as package_obj:
# use package_obj
</code></pre>
<p>变量package_obj将是package类型的实例(它是<code>__enter__</code>方法返回的值)。无论是否发生异常,它的<code>__exit__</code>方法都将被自动调用。</p>
<p>你甚至可以更进一步。在上面的示例中,有人仍然可以使用其构造函数实例化包,而不使用<code>with</code>子句。你不想发生这种事。可以通过创建定义<code>__enter__</code>和<code>__exit__</code>方法的PackageResource类来解决此问题。然后,包类将严格定义在<code>__enter__</code>方法内并返回。这样,调用方就无法在不使用<code>with</code>语句的情况下实例化包类:</p>
<pre><code>class PackageResource:
def __enter__(self):
class Package:
...
self.package_obj = Package()
return self.package_obj
def __exit__(self, exc_type, exc_value, traceback):
self.package_obj.cleanup()
</code></pre>
<p>你可以这样使用:</p>
<pre><code>with PackageResource() as package_obj:
# use package_obj
</code></pre>