在Python中导入多个文件

时间:2017-10-02 01:56:36

标签: python

我正在努力弄清楚如何处理导入多个文件中使用的依赖项。

假设我想导入外部API,例如,两个类依赖于此导入。将导入放入“索引”文件中,尝试将其设置为全局不起作用。我可以在每个类文件中导入它,但这似乎违反了DRY,以及稍后将自己设置为失败。

那么有一种方法可以在一个可全局访问的文件中导入一次吗?我尝试过的是创建index.pyfoo.py(对于foo类)和bar.py(对于bar类):

指数:

from example import API
import foo
import bar

foo()
bar()

foo.py:

class foo:
    ... (try to put the example API to use)

bar.py :(实际上与foo.py相同,只是为了说明在两个不同的地方使用相同的依赖关系)

这无效,因为类似乎无法访问exampleAPI。这样做的正确方法是什么,还是我看错了?谢谢!

1 个答案:

答案 0 :(得分:2)

通常,您应该在每个需要使用它的模块中导入所需的每个模块。您不必担心重复,因为每个模块都有自己的全局命名空间。此外,模块被缓存(在sys.modules字典中),因此您无需担心多次加载模块所需的额外工作。

那就是说,可能有一些例外。例如,如果API的特定源被视为“私有”信息(例如,因为它是一个实现细节,或者因为它可能是可配置的并且并不总是来自同一个地方),将它导入到其中可能是有意义的。所有其他用户都会寻找它的一些命名空间。

另一方面,您的示例表明您可能会比您应该更多地分割代码。与其他一些语言(如Java)不同,在Python中,每个类都不需要也不建议它们存在于自己的文件中。相反,您应该将代码划分为模块,这些模块由它们彼此之间的交互程度决定。紧密相关的类应该是同一模块的一部分,而完全不相互作用的部分可能在单独的模块中更有意义(特别是如果某些其他代码可能需要一个部分但不需要另一个部分)。整个程序可能不适合单个模块!显然,其中一些是风格和品味的问题,因此在每种情况下,每个程序员都没有一个最佳选择。

对于您的示例代码,如果您想保留单独的模块,我建议这样:

index.py

from foo import Foo # no need to import API here if you're not using it directly
from bar import Bar

foo = Foo() # create an instance of the foo class
result = foo.some_method() # call methods on it
bar = Bar(foo) # you can also pass your instances around to other classes

foo.py

from example import API

class Foo:
    def some_method(self):
        return API.whatever() # use the API in some way

bar.py

from example import API # don't worry about importing the API more than ocne

class Bar:
    def __init__(self, foo):
        self.foo = foo

    def blah(self):
        API.something_else(self.foo.some_method())

请注意,我改变了一些名字。 Python的惯例是对类使用CapitalizedNames,对模块,变量和方法使用lowercase_names_with_underscores(有时称为“蛇案例”)。您的原始代码似乎在模块名称foobar之间以及其中具有相同名称的类之间存在一些混淆。为不同的名称使用不同的样式可以帮助避免这种混淆。