我正在学习Python,今天在编写一些代码时,我试图决定在哪里放置import
语句。
我可以在任何地方放置一个import语句但是这个位置如何影响性能,命名空间以及我还不知道的任何其他内容?
答案 0 :(得分:3)
使用import
时,实际执行它的(模块)代码。因此,如果您可以控制执行它(例如,如果某些条件有效,则只需import
),然后将其放在任何您想要的位置。
if some_condition:
import foo
如果您总是需要(无条件),请将其放在文件的顶部。
对于初学者,我建议始终将import
语句放在文件的顶部。
答案 1 :(得分:3)
官方GoodPractice是将所有导入放在模块或脚本的开头,从标准的lib模块/包开始,然后是第三部分,然后是项目特定的,cf http://www.python.org/dev/peps/pep-0008/#imports
实际上,有时你必须将导入推迟到函数中作为循环依赖的快速和肮脏的解决方法(解决循环依赖的正确方法是在另一个模块中提取相关部分,但是有一些框架,你可以必须接受Q& D解决方法)。
将导入推迟到“表演”原因的功能并不是一个好主意恕我直言,但有时你有时必须打破规则。
导入模块实际上意味着:
search the module_or_package in `sys.modules`
if not found:
search the module_or_package_source in `sys.path`
if not found:
raise an ImportError
create a `module` instance from the module_or_package_source
# -> imply executing the top-level source code, which may raise anything
store the `module` instance in `sys.modules`
bind the `module` name (or whatever name was imported from it) in the current namespace
wrt /“当前命名空间”是什么意思,它实际上是这样的:命名空间(模块的“全局”,函数的“本地”或class
语句的主体),其中执行import
语句。这是一个包含所有三个示例的简单脚本:
try:
re
except NameError, e:
print "name 're' is not yet defined in the module's namespace"
print "module namespace : %s" % globals()
import re
print "name 're' is now defined in the module's namespace"
print "module namespace : %s" % globals()
def foo():
try:
os
except NameError, e:
print "name 'os' is not yet defined in the function's namespace"
print "function namespace : %s" % locals()
print "name 'os' is not defined in the module's namespace neither"
print "module namespace : %s" % globals()
import os
print "name 'os' is now defined in the function's namespace"
print "function namespace : %s" % locals()
print "name 'os' is still not defined in the module's namespace"
print "module namespace : %s" % globals()
foo()
print "After calling foo(), name 'os' is still not defined in the module's namespace"
print "module namespace : %s" % globals()
class Foo(object):
try:
os
except NameError, e:
print "name 'os' is not yet defined in the class namespace"
print "but we cannot inspect this namespace now so you have to take me on words"
print "but if you read the code you'll notice we can only get there if we have a NameError, so we have an indirect proof at least ;)"
print "name 'os' is not defined in the module's namespace neither obvisouly"
print "module namespace : %s" % globals()
import os
print "name 'os' is now defined in the class namespace"
print "we still cannot inspect this namespace now but wait..."
print "name 'os' is still not defined in the module's namespace neither"
print "module namespace : %s" % globals()
print "class namespace is now accessible via Foo.__dict__"
print "Foo.__dict__ is %s" % (Foo.__dict__)
print "'os' is now an attribute of Foo - Foo.os = %s" % Foo.os
print "name 'os' is still not defined in the module's namespace"
print "module namespace : %s" % globals()
答案 2 :(得分:0)
首次导入模块时,Python会搜索模块,如果找到,则会创建模块对象。
根据模块的大小以及在代码中使用它的频率,您可能希望将其导入一次并永远导入文件的顶部,或者您可能希望在特定时将其导入条件得到满足。
系统内存总是受到约束 - 如果很少有机会在极少数情况下满足模块的上述条件,那么根据条件检查进行导入是有意义的。
如果您需要在代码中导入多个重模块,这些模块会占用大量内存,但在不同的地方需要它们,这可能会特别有用。所以不要像
那样做import module1
import module2
def foo1()
module1.function()
def foo2()
module2.function()
foo1()
foo2()
尝试类似
的内容def foo1()
import module1
module1.function()
def foo2()
import module2
module2.function()
foo1()
foo2()
如果python模块足够简单,将它们包含在文件的顶部是有意义的 - 这些方式,正在阅读代码的任何人也可以事先了解当前代码使用的所有模块。
答案 3 :(得分:0)
导入通常放在文件的顶部,就像其他编程语言一样。将它们放在一起可以使模块的依赖性一目了然。
但是,由于import
执行模块的代码,因此可能是一项昂贵的操作,因此您有时会看到函数内部的导入。 NLTK是一个臭名昭着的重要模块,所以当我使用它时,我有时会这样做
def _tokenize(text):
import nltk
return nltk.word_tokenize(text)
def process_some_text(text):
if isinstance(text, basestring):
text = _tokenize(text)
# now do the actual processing
由于导入是缓存的,因此只有第一次调用_tokenize
才能导入。这也具有使依赖项可选的效果,因为在调用者请求相关功能之前不会尝试import
。
答案 4 :(得分:0)
您可以将它放在文件中的任何位置之前使用它。你应该 不通常把它放在循环中(因为它不会完全符合你的预期),但可能将它放在条件中。执行导入的模块初始化代码时,如果您知道自己需要它,可以只加载它来节省一些时间。
你可能将它放在函数中但如果在函数中则它只在该函数的范围内。 e.g。
>>> def f1():
... import sys
... print sys.version
...
>>> def f2():
... print sys.version
...
>>> f2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f2
NameError: global name 'sys' is not defined
>>> f1()
2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)]
>>> f2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f2
NameError: global name 'sys' is not defined
>>>
要遵循的一个好习惯是将它放在文件的顶部,以便它始终可用且易于查找。
您可能还会发现,特别是对于测试包组件,您可能需要在某些导入之前修改sys.path,以便尽早导入。
我个人发现有用的约定首先让你的所有系统导入,然后是项目包导入,然后是本地导入,并在它们之间添加适当的注释。
如果您import
modulename ,from
模块 import
子模块或{{1} } 模块 import
别名然后导入顺序应该没有重大区别但如果您as
模块< / em> from
然后 所有投注都关闭 ,因为各种模块可以定义相同的名称,最后一个将是你得到的 - 这只是其中一个不鼓励的原因。