Tok*_*Guy 62 python coding-style
我发现了一种新的模式.这种模式是众所周知的还是对它的看法是什么?
基本上,我很难刷新源文件以找出可用的模块导入等等,所以现在,而不是
import foo
from bar.baz import quux
def myFunction():
foo.this.that(quux)
Run Code Online (Sandbox Code Playgroud)
我将所有导入移动到它们实际使用的函数中,如下所示:
def myFunction():
import foo
from bar.baz import quux
foo.this.that(quux)
Run Code Online (Sandbox Code Playgroud)
这做了一些事情.首先,我很少意外地用其他模块的内容污染我的模块.我可以__all__为模块设置变量,但随后我必须在模块发展时更新它,这对于实际存在于模块中的代码无效.
其次,我很少在我的模块顶部进行一连串的进口,其中一半或更多我不再需要,因为我已经重构了它.最后,我发现这个模式更容易阅读,因为每个引用的名称都在函数体中.
aar*_*ing 110
这个问题的(先前)最高投票答案格式很好,但性能绝对错误.让我来证明一下
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
如您所见,在函数中导入模块可能更有效.这样做的原因是简单的.它将引用从全局引用移动到本地引用.这意味着,至少对于CPython,编译器将发出LOAD_FAST指令而不是LOAD_GLOBAL指令.顾名思义,这些更快.另一个回答者sys.modules通过在循环的每个迭代中导入来人为地夸大了查看的性能.
通常,最好在顶部导入,但如果您多次访问模块,性能不是原因.原因是人们可以更容易地跟踪模块所依赖的内容,并且这样做与Python Universe的其余部分一致.
Rya*_*yan 53
这确实有一些缺点.
如果您想通过运行时修改来测试模块,可能会使其变得更加困难.而不是做
import mymodule
mymodule.othermodule = module_stub
Run Code Online (Sandbox Code Playgroud)
你必须这样做
import othermodule
othermodule.foo = foo_stub
Run Code Online (Sandbox Code Playgroud)
这意味着您必须全局修补othermodule,而不是仅仅更改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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
dF.*_*dF. 21
这种方法存在一些问题:
py2exe,py2app等.所以...首选的方法是将所有导入放在文件的顶部.我发现如果我的导入很难跟踪,通常意味着我有太多的代码,我最好把它分成两个或更多的文件.
在那里我一些情况下已经发现里面进口的功能是有用的:
另外:在每个函数中放入导入实际上并不比文件顶部慢.第一次加载每个模块时,它被放入sys.modules,并且每个后续导入仅花费查找模块的时间,这相当快(不重新加载).
小智 10
另一个有用的注意事项是from module import *在Python 3.0中删除了函数内部的语法.
这里简单提一下"删除的语法":
http://docs.python.org/3.0/whatsnew/3.0.html
我建议你尽量避免from foo import bar进口。我只在包内使用它们,其中分成模块是一个实现细节,而且无论如何也不会有很多。
在导入包的所有其他地方,只需使用import foo然后通过全名引用它foo.bar。这样,您始终可以知道某个元素来自何处,而不必维护导入元素的列表(实际上,这将始终过时并导入不再使用的元素)。
如果foo是一个很长的名字,你可以用它来简化import foo as f,然后写成f.bar。这仍然比维护所有导入要方便和明确得多from。