我正在努力弄清楚如何处理导入多个文件中使用的依赖项。
假设我想导入外部API,例如,两个类依赖于此导入。将导入放入“索引”文件中,尝试将其设置为全局不起作用。我可以在每个类文件中导入它,但这似乎违反了DRY,以及稍后将自己设置为失败。
那么有一种方法可以在一个可全局访问的文件中导入一次吗?我尝试过的是创建index.py
,foo.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
。这样做的正确方法是什么,还是我看错了?谢谢!
答案 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
(有时称为“蛇案例”)。您的原始代码似乎在模块名称foo
和bar
之间以及其中具有相同名称的类之间存在一些混淆。为不同的名称使用不同的样式可以帮助避免这种混淆。