在 python 类中导入模块

Posted

技术标签:

【中文标题】在 python 类中导入模块【英文标题】:Importing modules inside python class 【发布时间】:2011-10-15 05:53:12 【问题描述】:

我目前正在编写一个需要osstat 和其他一些的类。

在我的班级中导入这些模块的最佳方式是什么?

我正在考虑其他人何时会使用它,我希望“依赖”模块已经存在 在类实例化时导入。

现在我在我的方法中导入它们,但也许有更好的解决方案。

【问题讨论】:

【参考方案1】:

This(搜索“Imports”部分)官方文件指出,imports 通常应该放在源文件的顶部。除了特殊情况,我会遵守这条规则。

【讨论】:

这是一种特殊情况。如果用户没有安装特定的库,您希望优雅地失败。假设你有一个脚本可以做很多事情,并且可以选择将日志推送到日志服务器。可能未安装日志服务器的库。如果是这种情况,您希望脚本仍然运行。如果用户配置了日志记录,我们可以打印错误然后退出。但是如果用户没有配置日志记录,脚本应该仍然能够在没有日志记录的情况下运行。将导入放在脚本顶部意味着如果没有安装库,它将一直失败。【参考方案2】:

PEP 8 导入:

导入总是放在文件的顶部,就在任何模块之后 cmets 和 docstrings,以及模块全局变量和常量之前。

这使得查看手头文件使用的所有模块变得容易,并且避免了在多个地方使用模块时必须在多个地方复制导入。其他一切(例如函数/方法级别的导入)都应该是一个绝对例外,并且需要很好地证明其合理性。

【讨论】:

这适用于无条件导入。如果您只想在实例化该类时导入它们,显然这不适用。 @agf:虽然很少有条件导入的理由。特别是对于 OP 使用的模块,这些可能已经被实现使用(尝试python -c "import sys; print sys.modules.keys()")。【参考方案3】:

如果您的模块将始终导入另一个模块,请始终将其作为PEP 8 放在顶部,其他答案表明。此外,正如@delnan 在评论中提到的那样,sysos 等无论如何都在使用,因此在全球范围内导入它们并没有什么坏处。

但是,如果您真的只需要在某些运行时条件下使用模块,那么条件导入并没有什么问题。

如果您只想在类已定义时导入它们,例如该类位于条件块或其他类或方法中,您可以执行以下操作:

condition = True

if condition:
    class C(object):
        os = __import__('os')
        def __init__(self):
            print self.os.listdir

    C.os
    c = C()

如果您只想在类实例化时导入它,请在__new____init__ 中进行。

【讨论】:

如果我在一个方法中导入一个模块(例如__init__),如果我创建多个实例,它不会多次导入该模块吗?因此,与全局导入相比,它会影响性能吗? 导入之后不应该是(),而不是[]?当我使用括号时,我收到错误“TypeError:'builtin_function_or_method' object has no attribute '__getitem'”。将其更改为 () 后,它可以工作,但是我必须在导入的模块前面加上类的名称,即使在类中使用导入的模块,我也不想这样做。有什么办法吗? @Samuel:感谢您的更正,我修复了导入。如果您希望导入的对象全局可用,只需使用普通的import 语句即可。不过,这对于条件导入来说并不是一个好主意,因为您可以在条件外部设置代码,该条件仅在具有导入的条件分支首先执行时才有效。如果像上面那样使用__import__,就可以避免为对象创建全局名称。 我明白了。我想要一个全局名称,但我想要一个条件导入。我正在根据用户选择的输出格式导入 xlsxwriter 模块,所以我并不总是想导入它。谢谢你的帮助!这告诉我什么是可能的以及如何去做。【参考方案4】:
import sys
from importlib import import_module

class Foo():

    def __init__(self):

        if self.condition:
            self.importedModule = import_module('moduleName')

        if 'moduleName' in sys.modules:
            self.importedModule.callFunction(params)

        #or

        if self.condition:
            self.importedModule.callFunction(params)

【讨论】:

以上是关于在 python 类中导入模块的主要内容,如果未能解决你的问题,请参考以下文章

在 ES 模块(Node.js)中导入 JSON 文件

如何在 lambda 中导入 python 模块?

模块可以在控制台导入,但不能在脚本中导入

python中pil如何导入?

Python:如何禁止从模块中导入类?

尽管尝试了多个建议,但无法在 Python 中导入本地模块