【问题标题】:Making a virtual package available via sys.modules通过 sys.modules 使虚拟包可用
【发布时间】:2010-09-26 22:51:39
【问题描述】:

假设我有一个包“mylibrary”。

我想让“mylibrary.config”可用于导入,可以作为动态创建的模块,也可以作为从完全不同的地方导入的模块,然后基本上“安装”在“mylibrary”命名空间内。

也就是说,我愿意:

import sys, types
sys.modules['mylibrary.config'] = types.ModuleType('config')

鉴于该设置:

>>> import mylibrary.config    # -> works

>>> from mylibrary import config
<type 'exceptions.ImportError'>: cannot import name config

甚至陌生人:

>>> import mylibrary.config as X
<type 'exceptions.ImportError'>: cannot import name config

所以看起来使用直接导入有效,其他形式没有。是否有可能使这些工作也有效?

【问题讨论】:

    标签: python import module


    【解决方案1】:

    您不仅需要将模块修补到 sys.modules 中,还需要修补到其父模块中:

    >>> import sys,types,xml
    >>> xml.config = sys.modules['xml.config'] = types.ModuleType('xml.config')
    >>> import xml.config
    >>> from xml import config
    >>> from xml import config as x
    >>> x
    <module 'xml.config' (built-in)>
    

    【讨论】:

      【解决方案2】:

      以及以下内容:

      import sys, types
      config = types.ModuleType('config')
      sys.modules['mylibrary.config'] = config
      

      你还需要这样做:

      import mylibrary
      mylibrary.config = config
      

      【讨论】:

        【解决方案3】:

        你可以试试这样的:

        class VirtualModule(object):
          def __init__(self, modname, subModules):
            try:
              import sys
              self._mod = __import__(modname)
              sys.modules[modname] = self
              __import__(modname)
              self._modname = modname
              self._subModules = subModules
            except ImportError, err:
              pass  # please signal error in some useful way :-)
          def __repr__(self):
            return "Virtual module for " + self._modname
          def __getattr__(self, attrname):
            if attrname in self._subModules.keys():
              import sys
              __import__(self._subModules[attrname])
              return sys.modules[self._subModules[attrname]]
            else:
              return self._mod.__dict__[attrname]
        
        
        VirtualModule('mylibrary', {'config': 'actual_module_for_config'})
        
        import mylibrary
        mylibrary.config
        mylibrary.some_function
        

        【讨论】:

          猜你喜欢
          • 2010-12-29
          • 1970-01-01
          • 2021-04-26
          • 2016-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多