使对象的行为类似于模块 - Python 3

时间:2014-03-18 00:22:23

标签: python python-3.x thrift

我想知道是否有办法让python变量表现得像python模块。

我目前遇到的问题是我们的API有python绑定。绑定是通过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()绑定到对象终止。可能是模块本身,如果可能的话。

编辑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)

1 个答案:

答案 0 :(得分:2)

导入模块不应导致网络连接。

如果您有强制设置/拆卸步骤,那么您可以定义上下文管理器:

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的自动生成模块应该是私有的,例如,将其命名为_thrift_client,并且在外部使用的适当的pythonic API应该在另一个模块中手动编写。

要回答标题中的问题:您可以使对象的行为类似于模块,例如,请参阅sh.SelfWrapperquickdraw.Module