2009-12-16 44 views
12

我有两个相关的Python导入问题。它们很容易测试,但我想要的是语言定义的而不是实现特定的答案,而且我对样式/约定也很感兴趣,所以我在这里问。Python导入机制

1)

如果模块A导入模块B和模块B模块进口C,可以在模块没有明确的进口代码的引用模块C?如果是这样,我认为这是不好的做法是正确的吗?

2)

如果我导入模块A.B.C,是否进口模块A和A·B以及?如果是这样,是否明确规定import A; import A.B; import A.B.C

+0

“语言定义的而不是实现特定的”你是说Python实现有些不同吗?你知道哪些具体的差异? AFAIK没有。 – 2009-12-16 21:49:45

+0

也许没有任何区别,但是规范未定义的任何内容都取决于实现。 Python文档散布着关于CPython实现细节的警告,这些细节可能不适用于其他实现。 – 2009-12-16 21:52:38

回答

12

您应该知道的第一件事是Python语言不是ISO标准。这与C/C++有很大不同,这意味着没有“正确”的方式来定义语言行为--CPython可能会做某些事情,只是因为它是以这种方式编码的,而Jython可能会这样做。

关于您的问题,请记住,“导入”模块是一个由两部分组成的操作:首先装载模块 - 如果它从未如此,例如如果它在sys.modules中不可用,那么名称将绑定到本地名称空间中的该模块。

因此:

1)是,可以通过提供适当的命名空间,例如引用任何你从模块一个想你必须做一些像

BCname =“东西”

而且我认为这是在Python程序很少做,可以被认为是不好的做法,因为它迫使“传递DEP” - 如果一些模块B实现被重构并且不再依赖于C,它应该继续提供C模块来满足A代价。

课程设置__ __都可以防止这种情况,和一个很好的做法可能是把所有__ __在所有的模块,并导出只是你想成为真正的公共符号。 2)是和不是。做

import a.b.c.d 

执行所有模块上的第一导入阶段(装载),但第二只是一个(并且递归地,在b相对于C,等),但在链中的所有模块都必须被全名称空间引用;这样的导入后,你可以做

a.something 
a.b.something 
a.b.c.something 

,但你不能做

c.something 
b.something 

我必须承认,一种用法是非常罕见的为好;我通常更喜欢“从模块导入某种东西”的方式导入,通常你只是问你需要什么 - 这种嵌套在图书馆中既不常见,也不常见。

很多时候,“外包装”只是用于组织,它们拥有类的模块。上面的a,b,c很可能只是包,而d是一个真正拥有类,函数和其他对象的模块。所以正确的用法是:

from a.b.c.d import name1, name2, name3 

我希望这能满足你的好奇心。

+0

感谢您的详细解答! – 2009-12-16 23:03:00

+0

虽然不是ISO,但有一个定义“正确”行为的Python语言参考,包括导入:http://docs.python.org/reference/simple_stmts.html#the-import-statement 语言参考指出CPython的实现细节,但其目标是成为该语言的通用规范,因此它不是全部依赖于实现。 – 2009-12-17 09:09:10

11

艾伦给出了一个很好的答案,但我想补充说,对于你的问题1,这取决于你的意思是“进口”。

如果使用from C import x语法,则在B的名称空间中可用x。如果在A中,然后您做import B,您有权访问xA作为B.x

这不是太糟糕的做法,因为可能会让人困惑,并且会使调试更困难,因为您不一定知道对象来自哪里。

+0

这是一个有用的说明,谢谢。我一直认为'import'与Java风格的软件包导入类似,但显然这种相似性仅仅是肤浅的。 – 2009-12-16 23:05:04

+0

如果令人困惑,是不是有足够的理由称之为坏习惯?应该明白什么代码只是通过阅读它恕我直言。 – jjpe 2015-04-14 18:06:27