在类/函数定义内部使用导入语句 - 这是个好主意吗?

61 投票
6 回答
60352 浏览
提问于 2025-04-16 13:26

我创建了一个叫做 util 的模块,这个模块里有我在Python中经常用到的类和函数。其中一些需要导入其他功能。把需要的东西放在类或函数内部导入有什么好处和坏处?这样做比在模块文件的开头导入要好还是不好?这样做合适吗?

6 个回答

4

就像飞羊的回答一样,我同意其他人的看法,但我在开发代码时会把导入放在其他地方,比如在 __init__() 函数和其他函数调用里。在我的类或函数经过测试并确认可以正常工作后,我通常会给它单独的模块,并按照PEP8的规范来处理导入。我这样做是因为有时候在重构代码或删除一些不好的旧代码后,我会忘记删除那些导入。通过把导入放在正在开发的类或函数里面,我可以明确它的依赖关系,这样如果我想把它复制到别的地方或者单独做成一个模块时,就会更方便...

18

PEP8是Python的风格指南,它提到:

导入的内容应该放在文件的最上面,紧接着模块的注释和文档字符串,然后再放模块的全局变量和常量。

当然,这并不是一个绝对的规则,你可以把导入放在任何你想放的地方。但把它们放在最上面是最好的做法。你当然也可以在函数或类里面进行导入。

不过要注意,你不能这样做:

def foo():
    from os import *

因为:

SyntaxWarning: import * only allowed at module level
60

在文件的顶部放置所有的导入语句是最常见的做法。PEP 8也推荐这样做,这就是一个很好的理由去遵循这个习惯。不过,这并不是随便的选择,它有一些好处(虽然这些好处并不是那么重要到让其他做法都变成错误)。这样做可以让你一眼就看到所有的导入,而不是要翻遍整个文件。它还确保在执行其他代码之前,所有需要的模块都已经被导入(因为其他代码可能依赖于这些导入)。NameError通常比较容易解决,但有时候会让人感到烦恼。

通过将模块保持在较小的范围内,实际上并没有什么(显著的)命名空间污染需要避免,因为你只添加了实际的模块(不,import *不算,而且可能也不应该使用)。在函数内部,你每次调用时都会重新导入(这其实并没有什么坏处,因为每个模块只会被导入一次,但这样做并不必要)。

撰写回答