2

我正在学习 Python,今天在编写一些代码时,我试图决定在哪里放置import语句。

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

4

5 回答 5

4

官方的 GoodPractice 是将所有导入放在模块或脚本的开头,从标准 lib 模块/包开始,然后是第三部分,然后是特定项目,参见http://www.python.org/dev/peps/pep -0008/#进口

实际上,您有时必须将导入延迟到函数中,作为循环依赖的快速而肮脏的解决方法(解决循环依赖的正确方法是在另一个模块中提取相关部分,但对于某些框架,您可能必须接受 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()
于 2013-10-10T10:32:48.373 回答
3

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

if some_condition:
    import foo

如果您总是需要(无条件)它,请将其放在文件的顶部。

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

于 2013-10-10T09:44:55.927 回答
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 模块足够简单,那么将它们包含在文件的顶部是有意义的——这样,阅读代码的任何其他人也可以预先了解当前代码使用的所有模块。

于 2013-10-10T09:56:12.700 回答
0

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

但是,由于 animport执行模块的代码,它可能是一项昂贵的操作,因此您有时会看到函数内部的导入。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在调用者请求相关功能之前不会尝试。

于 2013-10-10T09:57:36.113 回答
0

You can put it anywhere in the file before you use it. You should not normally put it in loops, (as it will not do quite what you expect) but may put it in conditionals. As the imported modules initialisation code is executed you might save a bit of time by only loading it if you know that you will need it.

You may put it within functions but if in function then it will only be in scope within that function. 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
>>>

A good convention to follow is to put it at the top of the files so that it is always available and easy to find.

You may also find, especially for testing package components that you may need to modify sys.path prior to some imports so that should be imported early.

A convention I personally find useful is to have all your system imports first then project package imports then local imports with appropriate comments between them.

If you import modulename, from module import submodule or import module as alias then import order should make no major difference but if you from module import * then all bets are off as various modules can define the same name and the last will be what you get - this is just one of the reasons that it is discouraged.

于 2013-10-10T09:59:00.590 回答