Cor*_*sky 12 python import coding-style module conventions
我有两个相关的Python'导入'问题.它们很容易测试,但我想要语言定义的答案,而不是特定于实现的答案,我也对样式/惯例感兴趣,所以我在这里问.
1)
如果模块A导入模块B,模块B导入模块C,可以在模块A参考模块C中编码而不进行显式导入吗?如果是这样,我认为这是不好的做法我是否正确?
2)
如果我导入模块ABC,那么导入模块A和AB吗?如果是这样,那么按惯例更好地明确import A; import A.B; import A.B.C吗?
Ala*_*oni 13
您应该知道的第一件事是Python语言不是ISO标准.这与C/C++有很大的不同,它意味着没有"正确"的方式来定义语言行为 - CPython可能只是因为它是以这种方式编码而做的,而Jython可能会反过来做.
关于你的问题,记住"导入"模块是一个由两部分组成的操作:首先加载模块 - 如果它从未被加载过,例如,如果它在sys.modules中不可用,那么一个名称被绑定到该模块在本地命名空间中.
因此:
1)是的,您可以通过提供适当的命名空间来引用模块a中的任何内容,例如,您必须执行类似的操作
BCname ="某事"
我认为在Python程序中很少这样做,并且可能被认为是不好的做法,因为它强制"传递dep" - 如果某个模块B实现被重构并且不再依赖于C,它应该继续提供C模块满足A deps.
当然设置__ all __可以防止这种情况,一个好的做法可能是将__ all __放在所有模块中,并只导出你想要公开的符号.
2)是和否.干
import a.b.c.d
Run Code Online (Sandbox Code Playgroud)
在所有模块上执行第一个导入阶段(加载),但第二个只在a上(并且,递归地,在b中相对于c等),但链中的所有模块必须由完整命名空间引用; 经过这样的导入,你可以做到
a.something
a.b.something
a.b.c.something
Run Code Online (Sandbox Code Playgroud)
但你做不到
c.something
b.something
Run Code Online (Sandbox Code Playgroud)
我必须承认,这种用法也很少见; 我通常更喜欢"从模块导入某种东西"的方式导入,通常你只是问你需要什么 - 这种嵌套在图书馆中既不常见,也不常见.
很多时候都有"外包装",只用于组织,它用于保存带有类的模块.上面的a,b,c很可能只是包,而d是一个真正保存类,函数和其他对象的模块.所以正确的用法是:
from a.b.c.d import name1, name2, name3
Run Code Online (Sandbox Code Playgroud)
我希望这能满足你的好奇心.
Dan*_*man 11
艾伦给出了一个很好的答案,但我想补充一点,问题1取决于你对"进口"的意思.
如果使用from C import x语法,则可x在命名空间中使用B.如果A你在那里import B,你将有权访问as .xAB.x
这并不是一个可能令人困惑的糟糕做法,并且会使调试等变得更难,因为你不一定知道对象来自哪里.