在python中,有关导入导入另一个模块的模块的问题?

时间:2018-04-21 22:36:41

标签: python python-3.x

我是一个python beginne,目前正在学习python中的导入模块。 所以我的问题是: 假设我目前有三个python文件,分别是module1.py,module2.py和module3.py;

在module1.py中:

def function1():
    print('Hello')

在module2.py中,为了在module1.py中使用这些函数:

import module1

#Also, I have some other public functions in this .py file
def function2():
    print('Goodbye')

#Use the function in module1.py
if __name__ == '__main__':
    module1.function1();
    function2();

在module3.py中,我想使用module1.py和module2.py。

中的两个函数
import module1
import module2

def function3():
    print('Nice yo meet you');

if __name__ == '__main__':
   module1.function1()
   function3()
   module2.function2()

好像很有效。但我的问题主要是关于module3.py。原因是在module3.py中,我导入了module1和module2。但是,module1已经由module2导入。我只是想知道这是一个很好的代码方式吗?这有效吗?我应该这样做吗?或者我应该避免这样做以及为什么?

非常感谢你。我只是一个初学者,所以如果我问愚蠢的问题,请原谅我。谢谢!!

1 个答案:

答案 0 :(得分:2)

如果你避免循环导入就没有问题,那就是你永远不会导入一个自己导入当前导入模块的模块。

模块没有看到导入器命名空间,因此导入器代码中的导入不会成为导入模块的全局变量。

此外,模块顶级代码仅在首次导入时运行。

编辑1:

我在这里回答菲利普的评论,因为它更容易。

“如果您避免循环导入将没有问题” - >这是不正确的,python在大多数情况下都是圆形导入。“

你感觉到我的一些误解的事实并没有使那个特定的陈述不正确。这是正确的,这是很好的建议。

(说大部分都没关系看起来有点像说大部分时间都会运行正常......)

我明白你的意思了。我避免这么多,以至于我甚至认为你的第一个例子会马上给出错误(事实并非如此)。你的意思是没有必要避免它,因为大多数时候(实际上给定某些条件)Python会很好用它。我也确信有些情况下,循环进口是最简单的解决方案。如果我们有选择的话,这并不意味着我们应该使用它们。这将促进使用糟糕的架构,其中每个模块都依赖于彼此。

这也意味着编码人员必须了解这些警告。

此链接我在SO中发现here表示对循环导入的一些担忧。

之前的链接有些陈旧,因此较新的Python版本信息可能已过时,但import confusion甚至更旧,仍然是3.6.2。

您提供的示例效果很好,因为相关或初始化模块代码包含在函数中,并且不会在导入时运行。使用if __name__ == "__main__":保护代码也会在导入时将其从运行中删除。

像这样简单的东西(来自effbot.org的相同例子)将不起作用(记住OP说他是初学者):

# file y.py
import x

x.func1()


# file x.py
import y

def func1():
    print('printing from x.func1')

在您的第二条评论中,您说: “这也是不正确的。导入的模块将成为命名空间的一部分”

是。但我没有提及,也没有相反。我只是说导入的模块代码不知道导入代码的命名空间。

为了消除歧义我只是意味着:

# w.py
def funcw():
    print(z_var)

# z.py
import w

z_var = 'foo'
w.funcw() # error: z_var undefined in w module namespace

运行z.py会显示错误。这就是我的意思。

现在进一步,为了获得我们想要的访问权限,我们进行循环......

# w.py
import z # go circular

def funcw():
    '''Notice that we gain access not to the z module that imported
       us but to the z module we import (yes its the same thing but
       carries a different namespace). So the reference we obtain
       points to a    different object, because it really is in a
       different namespace.'''

    print(z.z_var, id(z.z_var))

...我们保护一些代码免于运行导入:

# z.py
import w

z_var = ['foo']

if __name__ == '__main__':
    print(z_var, id(z_var))
    w.funcw()

通过运行z.py我们确认对象是不同的(它们可以与不可变对象相同,但这是python kerning - 内部优化或实现细节 - 在工作中):

['foo'] 139791984046856
['foo'] 139791984046536

最后,我同意你关于明确进口的第三条评论。

无论如何,我感谢你的评论。实际上,由于它们,我实际上提高了对问题的理解(我们通过避免它来学习很多东西)。