PEP 8规定:
导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,在模块全局变量和常量之前。
然而,如果我导入的类/方法/函数只在很少的情况下使用,那么在需要时进行导入肯定会更有效吗?
这不是:
class SomeClass(object):
def not_often_called(self)
from datetime import datetime
self.datetime = datetime.now()
比这更有效率?
from datetime import datetime
class SomeClass(object):
def not_often_called(self)
self.datetime = datetime.now()
我不太担心预先加载模块的效率。模块占用的内存不会很大(假设它足够模块化),启动成本可以忽略不计。
在大多数情况下,您希望在源文件的顶部加载模块。对于阅读代码的人来说,它可以更容易地区分哪个函数或对象来自哪个模块。
在代码的其他地方导入模块的一个很好的理由是,如果它在调试语句中使用。
例如:
do_something_with_x(x)
我可以用:
from pprint import pprint
pprint(x)
do_something_with_x(x)
当然,在代码的其他地方导入模块的另一个原因是,如果您需要动态导入它们。这是因为你几乎没有任何选择。
我不太担心预先加载模块的效率。模块占用的内存不会很大(假设它足够模块化),启动成本可以忽略不计。
在函数中导入变量/局部作用域可以提高性能。这取决于函数中导入对象的使用情况。如果你多次循环并访问一个模块全局对象,将它导入为本地会有帮助。
test.py
X=10
Y=11
Z=12
def add(i):
i = i + 10
runlocal.py
from test import add, X, Y, Z
def callme():
x=X
y=Y
z=Z
ladd=add
for i in range(100000000):
ladd(i)
x+y+z
callme()
run.py
from test import add, X, Y, Z
def callme():
for i in range(100000000):
add(i)
X+Y+Z
callme()
在Linux上的时间显示了一个小的增益
/usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python run.py
0:17.80 real, 17.77 user, 0.01 sys
/tmp/test$ /usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python runlocal.py
0:14.23 real, 14.22 user, 0.01 sys
真实的是挂钟。用户是程序中的时间。Sys是系统调用的时间。
https://docs.python.org/3.5/reference/executionmodel.html#resolution-of-names
Putting the import statement inside of a function can prevent circular dependencies.
For example, if you have 2 modules, X.py and Y.py, and they both need to import each other, this will cause a circular dependency when you import one of the modules causing an infinite loop. If you move the import statement in one of the modules then it won't try to import the other module till the function is called, and that module will already be imported, so no infinite loop. Read here for more - effbot.org/zone/import-confusion.htm