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

fly*_*ire 58 python python-import

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

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

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

例:

import string, pythis, pythat
...
...
...
...
def func():
     blah
     blah 
     blah
     from pysomething import foo
     foo()
     etc
     etc 
     etc
...
...
...
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*lli 63

PEP 8权威地指出:

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

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

  • 亚历克斯:这是“最佳实践”,但并非总是可以避免的。参见我上面给出的示例。 (3认同)
  • 我通常沉迷于“if __name__ == '__main__':”条件,其中模块需要导入 sys 或 argparse 以执行 i/o 如果它作为脚本调用,否则没有导入这些模块的任何理由。 (2认同)

ire*_*ses 18

2001年在Python邮件列表上对该主题进行了详细讨论:

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

  • 提出这一点是为了提供讨论的链接,而不仅仅是"PEP 8这样说".我会说它的"肉"会在线程中发出几条消息(http://mail.python.org/pipermail/python-list/2001-July/097866.html). (5认同)
  • 上面的链接已经死了,但这个链接似乎有效:https://mail.python.org/pipermail/python-list/2001-July/071567.html有些讨论可能会被删除. (5认同)
  • 这是一个仅限链接的答案,没有帮助.把你的答案的肉放在这里. (4认同)
  • http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers - 这就是为什么仅链接答案没有帮助的原因。 (2认同)

Mar*_*off 17

其他人都已经提到了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  
Run Code Online (Sandbox Code Playgroud)


Bla*_*ohr 12

如果导入的模块不经常使用且导入很昂贵,那么中间导入就可以了.

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


jkp*_*jkp 8

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

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

def detect(self):
    import foobar
Run Code Online (Sandbox Code Playgroud)

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

  • def中的导入肯定是可以避免的.我们使用`try:import x; 除了ImportError`逻辑块以保持所有导入前. (9认同)

Fro*_*kys 7

在文件开头将所有导入分组在一起被视为"良好格式".

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

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


jcd*_*yer 6

95%的情况下,您应该将所有导入放在文件的顶部.您可能希望执行函数本地导入的一种情况是,为了避免循环导入,必须执行此操作.假设foo.py导入bar.py,bar.py中的函数需要从foo.py导入一些东西.如果将所有导入放在顶部,则导入依赖于尚未编译的信息的文件时可能会出现意外问题.在这种情况下,具有本地导入功能可以允许代码在导入其他模块之前推迟其代码完全编译,并调用相关函数.

但是,看起来你的用例更多的是要明确foo()的来源.在这种情况下,我更喜欢以下两种情况之一:

首先,而不是

from prerequisite import foo
Run Code Online (Sandbox Code Playgroud)

直接导入先决条件,稍后将其称为prerequisite.foo.增加的详细程度通过提高代码透明度在自己中得到了回报.

或者,(或与上述相结合)如果你的导入和它正在使用的地方之间真的有这么长的距离,那么你的模块可能太大了.没有其他任何用途的导入需求可能表明您的代码可以被重构为更易管理的块.

  • 圆度可以通过分解来修复.有条件的进口 - 充其量 - 是一个笨重的解决方法.我说这是99.7%的时间,0.3%是"直到你可以分解来修复循环". (3认同)