导入应该在Python类内部还是外部? 概述

导入应该在Python类内部还是外部? 概述,python,Python,假设我正在构建一个用于一般用途的类:我可能需要在任何地方导入它,在几个其他文件中使用它,等等。如果导入在类之前,如下所示: import foo class Bar(): def __init__(self): foo.spam() 或者在\uuuu init\uuuu方法中,如下所示: class Bar(): def __init__(self): import foo foo.spam() 我的分析 外面 +将f

假设我正在构建一个用于一般用途的类:我可能需要在任何地方导入它,在几个其他文件中使用它,等等。如果导入在类之前,如下所示:

import foo

class Bar():

    def __init__(self):
        foo.spam()
或者在
\uuuu init\uuuu
方法中,如下所示:

class Bar():

    def __init__(self):

        import foo

        foo.spam()
我的分析 外面 +将
foo
引入全局命名空间,以便在整个
Bar

-导入
Bar
还需要手动导入
foo
(@MartijnPieters等人)

在…内 +避免在实际需要之前加载
foo

+
foo
在导入(并使用)实例化
Bar
时加载(@BrenBarn)


-
foo
在其他地方不可用

通常所有导入都位于模块顶部。这使得通过目视检查或在pyflakes之类的代码检查器中一目了然地查看模块的依赖关系变得很容易。您认为“导入
Bar
还需要手动导入
foo
”的假设是错误的


在函数或方法内部导入的唯一时间是当导入非常需要资源(例如,速度慢)或不可靠(例如,可能未安装的可选依赖项、特定于平台的模块或易于中断的模块)时,客户机代码并不总是调用有问题的函数。

还有一些相关的问题,等等。底线是,除非你有一个好的具体理由不这样做,否则通常最好把所有的进口放在首位

至于你的分析:

导入Bar还需要手动导入foo

不可以。导入Bar将自动导入foo,并且无论其他代码做什么,Bar都将能够使用foo。导入仅在执行导入的模块内创建对导入模块的引用(也就是说,它们不会使导入的名称在所有模块中“全局可用”)

  • 导入(和使用)条形图时加载foo
请注意,“导入”和“使用”不是一回事。在您的示例中,当Bar实例化时(使用
Bar()
),将导入
foo
,因为它位于
\uuuu init\uuu
方法内。导入条形图时不会加载它

  • 避免在实际需要之前加载foo
这是真的,但在实践中,它通常不会给你带来什么好处。只有在使用您的模块的人不需要使用导入
foo
(即
Bar
)的部件的可能性相当高的情况下,才有必要担心这一点。即使如此,只有在导入
foo
速度慢、资源密集或有时可能无法工作时(例如,如果
foo
是一个可能无法在所有平台上使用的库),才有意义。对于大多数模块,延迟导入几乎没有什么好处


这就引出了不进行本地导入的一个重要原因:它使了解模块的依赖关系变得更加困难。可以方便地查看模块顶部并查看需要导入的所有内容。如果关键的导入隐藏在代码的深处,则更难理解需要哪些其他模块可用。

导入栏还要求您手动导入foo:不,不需要<代码>条形图。_init__在其自己的模块中查找全局值。当为那些在所有平台上都不兼容的测试提供多平台单元测试时,我们在函数中进行导入(例如,仅在windows上导入winreg)