我发现了一种新的模式。这种模式是众所周知的还是有什么看法?
基本上,我很难清理上下源文件,以确定哪些模块导入是可用的等等,所以现在,代替
import foo
from bar.baz import quux
def myFunction():
foo.this.that(quux)
我将所有导入移到实际使用它们的函数中,如下所示:
def myFunction():
import foo
from bar.baz import quux
foo.this.that(quux)
这可以做一些事情。首先,我很少意外地用其他模块的内容污染我的模块。我可以为模块设置__all__
变量,但随后我必须随着模块的发展而更新它,这无助于实际存在于模块中的代码的命名空间污染。
其次,我很少在模块的顶部出现一连串的导入,其中一半或更多我不再需要,因为我已经重构了它。最后,我发现这个模式更容易阅读,因为每个引用的名称都在函数体中。
这个问题的top-voted answer格式很好,但在性能方面绝对错误。让我示范一下
性能
顶级进口
导入函数体
如您所见,在函数中导入模块可以更有效。原因很简单。它将引用从全局引用移动到本地引用。这意味着,至少对于CPython,编译器将发出
LOAD_FAST
指令,而不是LOAD_GLOBAL
指令。顾名思义,这些速度更快。另一个回答者通过在循环的每一次迭代中导入,人为地提高了查找sys.modules
的性能。通常,最好在顶部导入,但如果您多次访问该模块,则性能是而不是的原因。原因是可以更容易地跟踪模块所依赖的内容,并且这样做与Python世界的大多数其他部分是一致的。
这确实有一些缺点。
测试
如果您希望通过运行时修改来测试模块,那么这可能会使测试变得更加困难。而不是做
你必须这么做
这意味着您必须全局地修补othermodule,而不是仅仅更改mymodule中的引用所指向的内容。
依赖项跟踪
这使得模块所依赖的模块不明显。如果您使用许多第三方库或正在重新组织代码,这尤其令人恼火。
我不得不维护一些遗留代码,在所有地方都使用内联导入,这使得代码极难重构或重新打包。
业绩说明
由于python缓存模块的方式,性能没有受到影响。事实上,由于模块位于本地命名空间中,因此在函数中导入模块对性能有轻微的好处。
顶级进口
导入函数体
这种方法有几个问题:
py2exe
、py2app
等所以。。。首选方法是将所有导入放在文件的顶部。我发现,如果很难跟踪我的导入,通常意味着我有太多的代码,最好将其拆分为两个或更多文件。
在某些情况下,我发现函数内部的导入非常有用:
另外:将导入放在每个函数中实际上比放在文件顶部要慢得多。第一次加载每个模块时,它被放入
sys.modules
,而随后的每个导入只花费查找该模块的时间,这相当快(它不会重新加载)。相关问题 更多 >
编程相关推荐