11

假设我有一个包“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

所以似乎使用直接导入的作品,其他形式没有。是否也可以使这些工作?

4

3 回答 3

14

您不仅需要将模块修补到 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)>
于 2008-12-15T12:13:05.480 回答
2

以及以下内容:

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

你还需要做:

import mylibrary
mylibrary.config = config
于 2008-12-15T16:28:24.123 回答
1

你可以尝试这样的事情:

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
于 2008-12-15T12:41:41.227 回答