我想知道是否有办法让 python 变量表现得像 python 模块。
我目前遇到的问题是我们的 API 有 python 绑定(bind)。绑定(bind)是通过 swig 自动生成的,要使用它们,只需:
import module_name as short_name
short_name.functions()
现在我们正在研究使用 Apache Thrift 的 API。要使用它,有人需要:
client, transport = thrift_connect()
client.functions()
...
transport.close()
问题是我们有大量的脚本,我们想知道是否有一种方法可以让 thrift 客户端对象表现得像一个模块,这样我们就不需要修改所有脚本。我们的一个想法是做这样的事情:
client, transport = thrift_connect()
global short_name
short_name = client
__builtins__.short_name = client
这个“有点”有效。它创建了一个像模块一样的全局变量“short_name”,但它也会产生其他问题。如果其他文件导入相同的模块,则需要注释这些导入。此外,出于维护目的,拥有全局变量并不是一个好主意。
那么,有没有办法让 thrift 客户端表现得像一个模块呢?这样人们就可以继续使用“旧”语法,但在幕后模块导入会触发连接并返回对象作为模块?
编辑1:
每次导入都打开一个连接就可以了。也许我们可以使用某种单例,这样特定的解释器即使在不同文件上调用多个导入也只能打开一个连接。
我考虑过将 Transport.close() 绑定(bind)到对象终止。如果可能的话,可能是模块本身。
编辑2:
这似乎符合我的要求:
client, transport = thrift_connect()
attributes = dict((name, getattr(client, name)) for name in dir(client) if not (name.startswith('__') or name.startswith('_')))
globals().update(attributes)
最佳答案
导入模块不应导致网络连接。
如果您有强制性的设置/拆卸步骤,那么您可以定义一个上下文管理器:
from contextlib import contextmanager
@contextmanager
def thrift_client():
client, transport = thrift_connect()
client.functions()
try:
yield client
finally:
transport.close()
用法:
with thrift_client() as client:
# use client here
一般来说,具有类 C API 的自动生成模块应该是私有(private)的,例如,将其命名为 _thrift_client
并且在外部使用的正确的 Pythonic API 应手动编写在其之上另一个模块。
要回答标题中的问题:您可以使对象表现得像模块,例如,请参阅 sh.SelfWrapper
和 quickdraw.Module
.
关于python - 使对象表现得像模块 - Python 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22468092/