Python 中的好坏习惯:在文件中间导入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1188640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:40:51  来源:igfitidea点击:

Good or bad practice in Python: import in the middle of a file

pythonpython-import

提问by flybywire

Suppose I have a relatively long module, but need an external module or method only once.

假设我有一个相对较长的模块,但只需要一次外部模块或方法。

Is it considered OK to import that method or module in the middle of the module?

在模块中间导入该方法或模块是否可以?

Or should imports only be in the first part of the module.

或者应该import只在模块的第一部分。

Example:

例子:

import string, pythis, pythat
...
...
...
...
def func():
     blah
     blah 
     blah
     from pysomething import foo
     foo()
     etc
     etc 
     etc
...
...
...

Please justify your answer and add links to PEPs or relevant sources

请证明您的答案并添加指向PEP或相关来源的链接

回答by Alex Martelli

PEP 8authoritatively states:

PEP 8权威声明:

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,以及模块全局变量和常量之前。

PEP 8 should be the basis of any "in-house" style guide, since it summarizes what the core Python team has found to be the most effective style, overall (and with individual dissent of course, as on any other language, but consensus and the BDFL agree on PEP 8).

PEP 8 应该是任何“内部”风格指南的基础,因为它总结了核心 Python 团队发现的最有效的风格,总体而言(当然还有个人异议,就像对任何其他语言一样,但达成共识并且 BDFL 同意 PEP 8)。

回答by ire_and_curses

There was a detailed discussion of this topic on the Python mailing list in 2001:

2001 年 Python 邮件列表上有关于这个话题的详细讨论:

https://mail.python.org/pipermail/python-list/2001-July/071567.html

https://mail.python.org/pipermail/python-list/2001-July/071567.html

Here are some of the reasons discussed in that thread. From Peter Hansen, here are three reasons not to have imports all at the top of the file:

以下是该线程中讨论的一些原因。来自 Peter Hansen 的三个原因,不在文件的顶部全部导入:

Possible reasons to import in a function:

  1. Readability: if the import is needed in only one function and that's very unlikely ever to change, it might be clearer and cleaner to put it there only.

  2. Startup time: if you don't have the import outside of the function definitions, it will not execute when your module is first imported by another, but only when one of the functions is called. This delays the overhead of the import (or avoids it if the functions might never be called).

  3. There is always one more reason than the ones we've thought of until now.

在函数中导入的可能原因:

  1. 可读性:如果只在一个函数中需要导入并且不太可能改变,那么只将它放在那里可能会更清晰。

  2. 启动时间:如果你在函数定义之外没有导入,当你的模块第一次被另一个导入时它不会执行,只有当其中一个函数被调用时才会执行。这会延迟导入的开销(或者在函数可能永远不会被调用的情况下避免它)。

  3. 总有一个比我们迄今为止想到的更多的原因。

Just van Rossum chimed in with a fourth:

只是 van Rossum 附和第四个:

  1. Overhead: if the module imports a lot of modules, and there's a good chance only a few will actually be used. This is similar to the "Startup time" reason, but goes a little further. If a script using your module only uses a small subset of the functionality it can save quite some time, especially if the imports that can be avoided also import a lot of modules.
  1. 开销:如果模块导入了很多模块,并且很有可能只有少数模块会被实际使用。这类似于“启动时间”原因,但更进一步。如果使用您的模块的脚本仅使用一小部分功能,则可以节省相当多的时间,特别是如果可以避免的导入也导入了大量模块。

A fifth was offered as local imports are a way to avoid the problem of circular imports.

提供了五分之一,因为本地进口是避免循环进口问题的一种方式。

Feel free to read through that thread for the full discussion.

请随意通读该线程以进行完整的讨论。

回答by Mark Rushakoff

Everyone else has already mentioned the PEPs, but also take care to nothave import statements in the middle of critical code. At least under Python 2.6, there are several more bytecode instructions required when a function has an import statement.

其他人都已经提到了 PEP,但也要注意不要在关键代码中间使用 import 语句。至少在 Python 2.6 下,当函数具有 import 语句时,还需要更多的字节码指令。

>>> def f():
    from time import time
    print time()

>>> dis.dis(f)
  2           0 LOAD_CONST               1 (-1)
              3 LOAD_CONST               2 (('time',))
              6 IMPORT_NAME              0 (time)
              9 IMPORT_FROM              0 (time)
             12 STORE_FAST               0 (time)
             15 POP_TOP             

  3          16 LOAD_FAST                0 (time)
             19 CALL_FUNCTION            0
             22 PRINT_ITEM          
             23 PRINT_NEWLINE       
             24 LOAD_CONST               0 (None)
             27 RETURN_VALUE

>>> def g():
    print time()

>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (time)
              3 CALL_FUNCTION            0
              6 PRINT_ITEM          
              7 PRINT_NEWLINE       
              8 LOAD_CONST               0 (None)
             11 RETURN_VALUE  

回答by Blauohr

If the imported module is infrequently used and the import is expensive, the in-the-middle-import is OK.

如果导入的模块使用频率不高,导入成本高,中间导入就可以了。

Otherwise, is it wise to follow Alex Martelli's suggestion.

否则,遵循 Alex Martelli 的建议是否明智。

回答by jkp

It's generally considered bad practice, but sometimes it's unavoidable (say when you have to avoid a circular import).

这通常被认为是不好的做法,但有时它是不可避免的(例如,当您必须避免循环导入时)。

An example of a time when it is necessary: I use Wafto build all our code. The system is split into tools, and each tool is implemented in it's own module. Each tool module can implent a detect()method to detect if the pre-requisites are present. An example of one of these may do the following:

有必要的时候的一个例子:我使用Waf来构建我们所有的代码。该系统分为工具,每个工具都在它自己的模块中实现。每个工具模块都可以采用一种detect()方法来检测先决条件是否存在。其中之一的示例可以执行以下操作:

def detect(self):
    import foobar

If this works correctly, the tool is usable. Then later in the same module the foobarmodule may be needed, so you would have to import it again, at function level scope. Clearly if it was imported at module level things would blow up completely.

如果这正常工作,则该工具可用。然后稍后在同一模块中foobar可能需要该模块,因此您必须在功能级别范围内再次导入它。显然,如果它是在模块级别导入的,事情就会完全崩溃。

回答by Frozenskys

It is considered "Good Form" to group all imports together at the start of the file.

在文件开头将所有导入组合在一起被认为是“良好的形式”。

Modules can import other modules. It is customary but not required to place all import statements at the beginning of a module (or script, for that matter). The imported module names are placed in the importing module's global symbol table.

模块可以导入其他模块。习惯上但不需要将所有导入语句放在模块(或脚本,就此而言)的开头。导入的模块名称放置在导入模块的全局符号表中。

From here: http://docs.python.org/tutorial/modules.html

从这里:http: //docs.python.org/tutorial/modules.html

回答by jcdyer

95% of the time, you should put all your imports at the top of the file. One case where you might want to do a function-local import is if you have to do it in order to avoid circular imports. Say foo.py imports bar.py, and a function in bar.py needs to import something from foo.py. If you put all your imports at the top, you could have unexpected problems importing files that rely on information that hasn't been compiled yet. In this case, having a function local import can allow your code to hold off on importing the other module until its code has been fully compiled, and you call the relevant function.

95% 的情况下,您应该将所有导入放在文件顶部。您可能想要进行函数本地导入的一种情况是,您是否必须这样做以避免循环导入。假设 foo.py 导入了 bar.py,而 bar.py 中的一个函数需要从 foo.py 中导入一些东西。如果您将所有导入都放在顶部,那么导入依赖于尚未编译的信息的文件时可能会遇到意外问题。在这种情况下,使用本地导入函数可以让您的代码推迟导入另一个模块,直到其代码完全编译,并且您调用相关函数。

However, it looks like your use-case is more about making it clear where foo() is coming from. In this case, I would far prefer one of two things:

但是,看起来您的用例更多的是要弄清楚 foo() 的来源。在这种情况下,我更喜欢以下两种情况之一:

First, rather than

首先,而不是

from prerequisite import foo

import prerequisite directly, and later on refer to it as prerequisite.foo. The added verbosity pays itself back in spades through increased code transparency.

直接导入先决条件,稍后将其称为先决条件.foo。通过增加代码透明度,增加的冗长会得到回报。

Alternatively, (or in conjunction with the above) if it's really such a long distance between your import and the place it's being used, it may be that your module is too big. The need for an import that nothing else uses might be an indication of a place where your code could stand to be refactored into a more manageably-sized chunk.

或者,(或结合上述内容)如果您的导入和使用它的地方之间的距离真的很长,则可能是您的模块太大了。需要一个没有其他东西使用的导入可能表明你的代码可以被重构为一个更易于管理的块。

回答by Brian R. Bondy

PEP8:

PEP8

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,以及模块全局变量和常量之前。

It is not bad practice to have scopped imports. So that the import applies only to the function you used it in.

对进口进行范围限定是一种不错的做法。这样导入仅适用于您使用它的功能。

I think the code would be more readable though if the imports where grouped together at the top of the block or if you want it globally at the top of the file.

我认为代码会更具可读性,但如果导入在块的顶部组合在一起,或者如果您希望它全局位于文件的顶部。

回答by jab

Well, I think it is a good practice to group all imports together at start of file since everyone knows where to look if want to know which libs are loaded

好吧,我认为在文件开始时将所有导入组合在一起是一个很好的做法,因为如果想知道加载了哪些库,每个人都知道在哪里查看