<p>作为<a href="https://stackoverflow.com/a/865272/321973">Clint's answer</a>的附录,可以使用<a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" rel="noreferrer">^{<cd2>}</a>简化<code>PackageResource</code>:</p>
<pre><code>@contextlib.contextmanager
def packageResource():
class Package:
...
package = Package()
yield package
package.cleanup()
</code></pre>
<p>或者,虽然可能不是Pythonic,但是可以重写<code>Package.__new__</code>:</p>
<pre><code>class Package(object):
def __new__(cls, *args, **kwargs):
@contextlib.contextmanager
def packageResource():
# adapt arguments if superclass takes some!
package = super(Package, cls).__new__(cls)
package.__init__(*args, **kwargs)
yield package
package.cleanup()
def __init__(self, *args, **kwargs):
...
</code></pre>
<p>只需使用<code>with Package(...) as package</code>。</p>
<p>若要缩短时间,请将清理函数命名为<code>close</code>,然后使用<a href="https://docs.python.org/3/library/contextlib.html#contextlib.closing" rel="noreferrer">^{<cd6>}</a>,在这种情况下,可以通过<code>with contextlib.closing(Package(...))</code>使用未修改的<code>Package</code>类,也可以将其<code>__new__</code>重写为更简单的</p>
<pre><code>class Package(object):
def __new__(cls, *args, **kwargs):
package = super(Package, cls).__new__(cls)
package.__init__(*args, **kwargs)
return contextlib.closing(package)
</code></pre>
<p>这个构造函数是继承的,所以您可以简单地继承,例如</p>
<pre><code>class SubPackage(Package):
def close(self):
pass
</code></pre>