如何定义模块中与__all__分开的`from ... import *'api?

时间:2011-08-15 17:30:14

标签: python api python-3.x

我有一个模块,它在实用程序类型函数和核心api函数之间大致分成两半。我需要在__all__中使用所有这些以使help()有用,并且还要指定模块中的许多函数/类/等供外部使用,但我也想要支持from mymodule import *作为将核心功能引入其他模块的方法。有没有办法做到这一点?

4 个答案:

答案 0 :(得分:4)

几乎。虽然你不能以这种方式让__all__做双重任务,但你可以添加自己的虚拟api模块,然后可以导入...

class fake_module(object):
    def __init__(self, name, *args):
        self.name = name
        self.__all__ = []
        all_objects = globals()
        for name in args:
            self.__dict__[name] = all_objects[name]
            self.__all__.append(name)
    def register(self):
        sys.modules["%s.%s" % (__name__, self.name)] = self

    fake_module('api', 'class1', 'class2', 'func3', 'exception4').register()

然后在其他模块而不是from mymodule import *中,您可以from mymodule.api import *来获取所需的子集,同时仍将所有内容保存在单个模块中。

注意from ... import *通常不是一种好习惯,应谨慎使用,并且只能使用明确说明设计时考虑过此类用途的模块/软件包。

答案 1 :(得分:4)

Ethan,你的fake_module可能更适合普通的老蟒蛇。只需将代码移动到目录设置中:

mymodule
    __init__.py
    api.py
    util.py
    _mymodule.py

_mymodule.py包含您当前的代码。

__init__.py

from _mymodule import * 

在你api.py

# explicity import only those api classes you want to expose
# this will allow you to call `from mymodule.api import *`
import from _mymodule ApiClass1
import from _mymodule ApiClass2
# etc  

util.py

执行相同的操作
# explicity import only those util classes you want to expose
# this will allow you to call `from mymodule.util import *`
import from _mymodule UtilClass1
import from _mymodule UtilClass2
# etc

现在你可以:

# import everything willy nilly for your help()
from mymodule import *

# or import only the "public" values from api and util
from mymodule.api import *
from mymodule.util import *

像这样分解你的代码对于组织一个你仍然希望能够从顶级命名空间访问的较大模块非常有用。但我必须同意brandizzi在使用此模块的代码中使用from mymodule import *通常是一个坏主意。您在导入时容易获得的东西会失去使用这些导入的代码的透明度。

答案 2 :(得分:2)

我认为没有办法做到这一点 - 至少不是一个干净的方式。甚至Python官方模块也在其文档中出现了许多util函数。如果分离很重要,我会做的是创建两个不同的模块。无论如何,使用from module import *并不是一个好习惯,我不建议你去做,更不用说设计你的模块来适应这种做法了:)

答案 3 :(得分:0)

您无法拥有自己想要的内容:import *行为由__all__定义。