我正在设计基于python的API。目前,我遇到了两个不同要求的问题。一方面,我想提供清理API相关资源的可靠方法。因此,据我所知,最好的方法是使用上下文管理器,如:
# lib
class Client(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, tb):
do_cleanup()
def method1(self):
pass
def method2(self):
pass
# api user
import mylib
with mylib.Client() as client:
client.method1()
client.method2()
另一方面,我想提供一种在交互式解释器中无缝使用我的lib的方法。
但是在解释器中使用像with
或try-except-finally
这样的复合构造使得解释器的使用不那么常规,因为with
- 块被视为单个语句。并且最好每个单独的api方法使用单个语句,如:
# interpreter session
>>> import mylib
>>> client = mylib.Client()
<client object at ...>
>>> client.method1()
True
>>> client.method2()
100
那么,我可以在这里有任何选择吗?肯定有一种方法可以为脚本和解释器提供不同的使用语义,但我想将它作为最后的手段。
答案 0 :(得分:2)
执行此操作的典型方法是提供手动执行清理的方法,并__exit__
调用该方法。对于您的示例,如果将do_cleanup
实现为方法,则可以在完成后从解释器中调用它。
class Client(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, tb):
self.do_cleanup()
def do_cleanup(self):
pass
def method1(self):
pass
def method2(self):
pass
然后,在翻译中:
>>> import mylib
>>> client = mylib.Client()
<client object at ...>
>>> client.method1()
True
>>> client.method2()
100
>>> client.do_cleanup()
我建议将do_cleanup
重命名为close
或类似名称,以便File Objects之间的相似性更明显。
答案 1 :(得分:0)
你可以创建你的基础&#39;具有open
和close
函数的逻辑,在实现模块中,并使用上下文管理器扩展这些类:
#in private module mymodule.impl
class Base(object):
def open(self, ...):
...
def close(self):
...
客户端代码通常不包含此文件。
相反,客户端代码导入exported.api
,如下所示:
#in public package mymodule
import mymodule.impl
class Base(mymodule.impl.Base):
def __enter__(self):
return self
def __exit__(self, ...):
self.close()