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

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

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

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

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

【问题讨论】:

    标签: python class import module


    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2020-07-23
      • 1970-01-01
      • 2020-01-10
      • 2011-02-11
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多