【问题标题】:How to import a class from a module from a package dynamically?如何从包中动态导入模块中的类?
【发布时间】:2011-04-04 10:59:48
【问题描述】:

这可能很简单,但我不明白。以下作品:

foo.py

class Foo:
    pass

bar.py

module = __import__('foo')
foo = module.__dict__['Foo']

之后,foo 就像预期的那样是 foo.Foo 类。


然而,如果我将a.py 放入一个包中,它就会停止工作:

qux/__init__.py

(空文件)

qux/foo.py

class Foo:
    pass

bar.py

module = __import__('qux.foo')
foo = module.__dict__['Foo']

运行python bar.py 给我KeyError: 'Foo',但模块导入仍然成功。

发生了什么,我该如何让它发挥作用?

【问题讨论】:

    标签: python import module


    【解决方案1】:

    您可以使用importlib 直接访问模块,无论是否嵌套:

    import importlib
    module_name="qux.foo"
    mod=importlib.import_module(module_name)
    

    更多详情请见http://docs.python.org/dev/library/importlib.html

    【讨论】:

      【解决方案2】:

      您需要使用 fromlist 参数来引用子模块:

      temp = __import__('qux.foo', globals(), locals(), ['Foo'], -1)
      foo = temp.Foo
      

      【讨论】:

        【解决方案3】:

        如果你想导入一个子模块,你可以这样做:

        package = __import__('qux', fromlist=['foo'])
        module = getattr(package, 'foo')
        

        注意fromlist __import__ 在第一个参数中返回嵌套最多的名称,因此您可以在__import__ 调用中替换baz.bar.qux 以访问baz.bar.qux.foo 模块。

        【讨论】:

          【解决方案4】:

          __import__ 应用于嵌套模块名称返回顶级模块/包 - 此处为 qux。但是,所有模块都插入到sys.modules,因此您可以在其中简单地查找qux.foo

          请参阅__import__() 上的 PyDoc - 那里都有描述。

          【讨论】:

          • 请注意,“import qux.foo”的工作方式类似——qux 最终位于本地命名空间中,但 foo 只能作为 qux 的属性访问。
          • 确实,当我再次查看时,它突然神秘地出现在文档中:“当名称变量的形式为 package.module 时,通常是顶级包(直到返回第一个点),而不是按名称命名的模块。但是,当给出非空的 fromlist 参数时,返回按名称命名的模块。"
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-09-19
          • 2018-12-14
          • 2019-03-24
          • 2020-11-30
          • 1970-01-01
          • 2017-07-13
          • 1970-01-01
          相关资源
          最近更新 更多