假设我有一个主脚本main.py,用import coolfunctions
和另一个导入另一个python文件:import chores
现在,假设coolfunctions也使用来自家务的东西,因此我在coolfunctions中声明import chores
。
因为main.py和coolfunctions导入家务〜这是多余的吗?有没有其他方法这样做?我这样做了吗?
我对如何构建python项目感到困惑。我有一个“conf.py”文件,我导入了一堆变量〜这是一个模块还是没有?我也在多个地方加载这个conf文件。
答案 0 :(得分:2)
如果两个模块想要使用chores
,则每个必须 import chores
(或某些等效导入)。每个导入仅在执行导入的模块的命名空间中创建名称绑定;也就是说,import
的命名空间效果是模块命名空间的本地。
这很好,因为通过查看模块的代码,您可以(禁止病态案例)通过将模块或模块属性显式绑定到名称的import语句知道每个名称绑定到的位置。在其他模块中进行的导入不会影响该模块的命名空间。
答案 1 :(得分:1)
不,这不是多余的 - 在主模块和import chores
中coolfunctions
都没问题。
Python的确切导入机制很复杂(例如,模块导入只执行一次,意味着在你的情况下,chores
模块的实际解析和加载只会发生一次,这是一个很好的优化)但总的来说你不应该担心它,因为它只是起作用。
每个Python文件都是一个模块,因此您的conf.py
也是一个模块。
答案 2 :(得分:1)
每个模块X应该导入所有(并且只有)模块Y,Z,T ......,它们需要的功能,而不用担心其他模块费,Fie,Foo ...(如果有的话)可能有什么已完成部分或全部进口,或将来可能会这样做。
如果每个模块都不得不担心这种微妙的“隐蔽通道”效应,它会使模块非常脆弱(事实上,它将与模块化完全相反!)。
X,Z,T,......,每个模块X选择导入的模块(如果有的话)是X的实现细节的一部分,除了编码,测试或维护的开发人员之外,不应该涉及任何人X
为了确保这种情况,并且这种明显最佳的解耦策略可以并且将完全遵循理智的代码,Python在导入时“缓存”模块:模块仅“加载”一次每次运行一个程序,任何人第一次导入它(或其中任何东西) - 所有其他导入使用第一次加载获得的相同对象,Python保存在缓存中(指定为dict {{ 1}},但你需要知道这些细节只适用于某些高级编程技术......不要担心它,98.7%的时间 - 只记得“导入很便宜”! - )。
当然,您通过sys.modules
从其他几个模块中使用的conf.py
绝对是一个模块(您可能认为您正在多次加载它,但除非您正在使用,否则您不会确实非常先进和深思熟虑的技术) - 为什么不应该这样?
答案 3 :(得分:0)
在使用它们的文件中导入所有必需的模块始终是最佳做法。举个例子:
A.py包含:import coolfunctions
B.py包含:import A
Main.py包含:import B
并使用A.py中定义的函数(这是可能的,因为通过导入B,Main.py导入了B导入的所有内容)
如果以后您将B.py更改为无需导入A.py并因此删除import A
,那么您的Main.py将失去未导入A.