Python 从哪里进口?

Python 从哪里进口?,python,Python,我正在学习Python,今天在编写一些代码时,我试图决定将import语句放在何处 我可以将import语句放在任何地方,但位置如何影响性能、名称空间以及其他我不知道的内容?当您使用import时,实际上执行的是(模块)代码。因此,如果您可以控制执行它(例如,如果某些条件起作用,您只需要import),然后将它放在您想要的任何地方 if some_condition: import foo 如果你总是需要(没有条件)它,那么把它放在你的文件的顶部 对于初学者,我建议始终将import语

我正在学习Python,今天在编写一些代码时,我试图决定将
import
语句放在何处


我可以将import语句放在任何地方,但位置如何影响性能、名称空间以及其他我不知道的内容?

当您使用
import
时,实际上执行的是(模块)代码。因此,如果您可以控制执行它(例如,如果某些条件起作用,您只需要
import
),然后将它放在您想要的任何地方

if some_condition:
    import foo
如果你总是需要(没有条件)它,那么把它放在你的文件的顶部


对于初学者,我建议始终将
import
语句放在文件的顶部。

当第一次导入模块时,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模块足够简单,那么将它们包含在文件的顶部是有意义的——这样,阅读代码的任何其他人都可以事先了解当前代码使用的所有模块。

导入通常放在文件的顶部,就像在其他编程语言中一样。将它们放在一起可以很容易地一目了然地查看模块的依赖关系

但是,由于导入执行模块的代码,因此这可能是一个昂贵的操作,因此您有时会在函数中看到导入。是一个非常重的模块,所以当我使用它时,我有时会这样做

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

因为导入是缓存的,所以只有对
\u tokenize
的第一次调用才会进行导入。这还具有使依赖项成为可选的效果,因为在调用方请求相关功能之前不会尝试导入。

在使用它之前,您可以将它放在文件中的任何位置。你应该通常把它放在循环中,(因为它不会像你期望的那样),但是可以把它放在条件中。在执行导入的模块初始化代码时,如果您知道需要,只需加载它,可能会节省一些时间

您可以将它放在函数中,但如果在函数中,则它将仅在该函数的作用域中。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
>>>
>>def f1():
...    导入系统
...    打印系统版本
...
>>>def f2():
...    打印系统版本
...
>>>f2()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第2行,在f2中
NameError:未定义全局名称“sys”
>>>f1()
2.5.4(r254:6791620008年12月23日,15:10:54)[MSC v.1310 32位(英特尔)]
>>>f2()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第2行,在f2中
NameError:未定义全局名称“sys”
>>>
遵循的一个好习惯是将它放在文件的顶部,这样它总是可用且易于查找

您还可能会发现,特别是对于测试包组件,您可能需要在某些导入之前修改sys.path,以便尽早导入

我个人认为有一个惯例很有用,那就是先进行所有系统导入,然后进行项目包导入,然后进行本地导入,并在它们之间添加适当的注释


如果您
导入
模块名,
from
module
import
submodule或
import
module
as
别名,则导入顺序应无重大区别,但如果您
from
module
import*
所有赌注均已取消,因为各个模块可以定义相同的名称,最后一个将是您想要的名称get-这只是不鼓励使用它的原因之一。

官方的良好做法是将所有导入放在模块或脚本的开头,从标准库模块/包开始,然后是第三部分,然后是特定于项目的,cf

实际上,您有时不得不推迟导入到函数中,以作为循环依赖项的快速而肮脏的解决方法(解决循环依赖项的正确方法是提取另一个模块中的相关部分,但对于某些框架,您可能必须接受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/什么是“当前名称空间”,它实际上是这样的:名称空间(模块的“全局”、函数的“局部”或
语句体),在其中执行
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()

该模块仅在第一次导入时执行(“第一次”用于当前的Python进程)。然后将其缓存到
sys.modules
中,随后的导入将只执行本地名称空间绑定部分。实际上,“使依赖项可选”实际上意味着代码将在任何不可预测的时间失败,而不是在进程启动时失败(当所有导入都处于顶级时)@Brunodesshuilliers:这是可以记录的,而且可以捕获
importorror
,并将其转换为更友好的错误消息。的确如此,但从经验来看,它可能会使流程崩溃(从未见过这种情况被明确记录或处理)。该模块只在第一次执行一次