在类/函数定义中导入语句 - 这是一个好主意吗?

时间:2011-03-10 16:10:17

标签: python function class import

我创建了一个名为util的模块,它提供了我经常在Python中使用的类和函数。 其中一些需要导入功能。在类/函数定义中导入所需内容的优点和缺点是什么?它是否比模块文件开头的import好?这是个好主意吗?

6 个答案:

答案 0 :(得分:46)

每个导入放在文件顶部是最常见的样式。 PEP 8推荐它,这是开始这样做的一个很好的理由。但这不是一时兴起,它具有优势(虽然不足以使其他一切成为犯罪)。它允许一目了然地查找所有导入,而不是查看整个文件。它还确保在执行任何其他代码(可能取决于某些导入)之前导入所有内容。 NameError通常很容易解决,但它们可能很烦人。

通过将模块保持在较小的范围内,可以避免(重要的)命名空间污染,因为您添加的只是实际模块(no, import * doesn't count and probably shouldn't be used anyway)。在内部函数中,你会在每次调用时再次导入(因为所有内容都被导入一次,所以不是真的有害,但是不需要)。

答案 1 :(得分:13)

Python样式指南

PEP8指出:

  

进口总是放在首位   文件,就在任何模块之后         注释和文档字符串,以及模块全局和常量之前。

当然,这不是硬性规定,进口可以在任何你想要的地方进行。但把它们放在首位是最好的方法。您当然可以在函数或类中导入。

但请注意,你不能这样做:

def foo():
    from os import *

由于:

SyntaxWarning: import * only allowed at module level

答案 2 :(得分:2)

我认为最好的做法(根据某些PEP的说法)是在模块开头保留import语句。您可以将导入语句添加到__init__.py文件,该文件会将这些模块导入包中的所有模块。

所以...这肯定是你可以按照你的方式做的事情,但它是气馁的,实际上是不必要的。

答案 3 :(得分:2)

虽然其他答案大多是正确的,但是有一个原因可以让python允许这样做。

导入不需要的冗余内容并不明智。所以,如果你想要,例如将XML解析为元素树,但如果lxml可用,则不想使用慢内置XML解析器,您需要在需要调用解析器时检查它。

而不是在开始时记住lxml的可用性,我宁愿try导入并使用lxmlexcept它不存在,在这种情况下我会回退到内置xml模块。

答案 4 :(得分:2)

就像飞羊的回答一样,我同意其他人是正确的,但是当我开发代码时,我将导入放在其他地方,例如__init__()例程和函数调用。在我的类或函数经过测试并证明可以使用其中的导入后,我通常会给它自己的模块,其导入遵循PEP8指南。我这样做是因为有时我忘记在重构代码或删除带有错误想法的旧代码后删除导入。通过保持开发中的类或函数内的导入,我指定其依赖项,如果我想将其复制到别处或将其提升到自己的模块...

答案 5 :(得分:0)

如果需要解决诸如避免循环导入之类的问题或者尝试减少模块的初始化时间,则仅将导入移动到本地范围(例如函数定义内)。如果根据程序的执行方式不需要许多导入,这种技术特别有用。如果模块仅在该函数中使用过,您可能还希望将导入移动到函数中。请注意,由于模块的一次初始化,第一次加载模块可能很昂贵,但是多次加载模块几乎是免费的,仅花费几次字典查找。即使模块名称超出范围,该模块也可能在sys.modules中可用。

https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module