Python导入编码风格

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (26)

我发现了一种新的模式。这种模式是众所周知的还是有什么看法?

基本上,我很难上下清理源文件,找出哪些模块导入是可用的等等,所以现在,而不是

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__变量,但是随着模块的发展,我将不得不更新它,这无助于模块中的代码名称空间污染。

第二,我很少会在模块顶部出现一系列的导入,其中一半或更多的导入不再需要,因为我已经对其进行了重构。最后,我发现这个模式更容易阅读,因为每个引用的名称都在函数体中。

提问于
用户回答回答于

这确实有一些缺点。

测试

如果您希望通过运行时修改来测试模块,这可能会使测试变得更加困难。而不是做

import mymodule
mymodule.othermodule = module_stub

你得做

import othermodule
othermodule.foo = foo_stub

这意味着您必须对其他模块进行全局修补,而不是仅仅更改myModule中的引用指向的内容。

依赖跟踪

这使得模块所依赖的模块并不明显。如果您使用了许多第三方库或正在重新组织代码,这尤其令人恼火。

我不得不维护一些遗留的代码,这些代码在所有地方都使用了导入,这使得代码很难重构或重新打包。

关于表演的说明

由于python缓存模块的方式,没有性能上的影响。实际上,由于模块位于本地命名空间中,因此在函数中导入模块会带来轻微的性能好处。

顶级进口

import random

def f():
    L = []
    for i in xrange(1000):
        L.append(random.random())

for i in xrange(10000):
    f()


$ time python test.py 

real   0m1.569s
user   0m1.560s
sys    0m0.010s

导入功能体

def f():
    import random
    L = []
    for i in xrange(1000):
        L.append(random.random())

for i in xrange(10000):
    f()

$ time python test2.py

real    0m1.385s
user    0m1.380s
sys     0m0.000s
用户回答回答于
import random

def f():
    L = []
    for i in xrange(1000):
        L.append(random.random())


for i in xrange(1000):
    f()

$ time python import.py

real        0m0.721s
user        0m0.412s
sys         0m0.020s

导入功能体

def f():
    import random
    L = []
    for i in xrange(1000):
        L.append(random.random())

for i in xrange(1000):
    f()

$ time python import2.py

real        0m0.661s
user        0m0.404s
sys         0m0.008s

正如你所看到的,它可以是更多高效导入模块中的功能。原因很简单。它将引用从全局引用移动到本地引用。这意味着,至少对于cpython,编译器将发出LOAD_FAST指令而不是LOAD_GLOBAL指示。顾名思义,这些更快。另一个回答者人为地夸大了往内看的表现。sys.modules通过导入循环的每一次迭代天龙八部

一般来说,最好在顶部导入,但是性能是如果您多次访问该模块的原因。其原因是,您可以更容易地跟踪模块依赖于什么,并且这样做与Python宇宙的大多数其他部分是一致的。

扫码关注云+社区

领取腾讯云代金券