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

时间:2022-12-20 02:45:41

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.

或者应该只导入模块的第一部分。

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

请证明你的答案,并添加链接到PEPs或相关的来源

9 个解决方案

#1


49  

PEP 8 authoritatively 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.

导入总是放在文件的顶部,在任何模块注释和docstring之后,在模块全局变量和常量之前。

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)。

#2


17  

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

#3


14  

Everyone else has already mentioned the PEPs, but also take care to not have 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.

其他人都已经提到了PEPs,但也要注意在关键代码中间不要有导入语句。至少在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  

#4


10  

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.

否则,听从阿历克斯·马尔泰利的建议是否明智?

#5


8  

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 Waf to 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 foobar module 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模块,因此必须在函数级范围内再次导入它。显然,如果是在模块级导入的话,事情就会完全崩溃。

#6


7  

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

#7


6  

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进口酒吧。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.

或者,(或与上面的结合)如果您的导入和所使用的位置之间真的有这么长的距离,可能您的模块太大了。对于没有其他用途的导入的需求,可能表明您的代码可以被重构到更易于管理的块中。

#8


2  

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.

导入总是放在文件的顶部,在任何模块注释和docstring之后,在模块全局变量和常量之前。

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.

我认为代码会更容易理解,但是如果在块的顶部组合在一起或者在文件的顶部需要全局的时候。

#9


2  

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

我认为在文件开始时将所有导入集合在一起是一种很好的实践,因为如果想知道加载了哪些lib,每个人都知道应该查看哪里

#1


49  

PEP 8 authoritatively 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.

导入总是放在文件的顶部,在任何模块注释和docstring之后,在模块全局变量和常量之前。

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)。

#2


17  

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

#3


14  

Everyone else has already mentioned the PEPs, but also take care to not have 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.

其他人都已经提到了PEPs,但也要注意在关键代码中间不要有导入语句。至少在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  

#4


10  

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.

否则,听从阿历克斯·马尔泰利的建议是否明智?

#5


8  

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 Waf to 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 foobar module 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模块,因此必须在函数级范围内再次导入它。显然,如果是在模块级导入的话,事情就会完全崩溃。

#6


7  

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

#7


6  

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进口酒吧。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.

或者,(或与上面的结合)如果您的导入和所使用的位置之间真的有这么长的距离,可能您的模块太大了。对于没有其他用途的导入的需求,可能表明您的代码可以被重构到更易于管理的块中。

#8


2  

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.

导入总是放在文件的顶部,在任何模块注释和docstring之后,在模块全局变量和常量之前。

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.

我认为代码会更容易理解,但是如果在块的顶部组合在一起或者在文件的顶部需要全局的时候。

#9


2  

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

我认为在文件开始时将所有导入集合在一起是一种很好的实践,因为如果想知道加载了哪些lib,每个人都知道应该查看哪里