【发布时间】:2012-09-10 13:21:02
【问题描述】:
我正在将 jython 与第三方应用程序一起使用。第三方应用程序有一些内置库foo。为了进行一些(单元)测试,我们希望在应用程序之外运行一些代码。由于foo 绑定到应用程序,我们决定编写自己的模拟实现。
但是有一个问题,我们在 python 中实现了我们的模拟类,而他们的类是在 java 中。因此,要使用他们的代码,可以使用 import foo 并且 foo 是之后的模拟 class。但是,如果我们像这样导入 python 模块,我们会在名称上附加 module,因此必须写 foo.foo 才能进入该类。
为方便起见,我们希望能够编写 from ourlib.thirdparty import foo 以将 foo 绑定到 foo-类。但是我们希望避免直接导入ourlib.thirdparty 中的所有类,因为每个文件的加载时间都需要相当长的时间。
在python中有什么办法吗? (Import hooks 并没有走多远,我尝试简单地从load_module 返回类或覆盖我写给sys.modules 的内容(我认为这两种方法都很丑陋,尤其是后者))
编辑:
好的:这是 ourlib.thirdparty 中的文件看起来简化后的样子(没有魔法):
foo.py:
try:
import foo
except ImportError:
class foo
....
实际上它们看起来像这样:
foo.py:
class foo
....
__init__.py in ourlib.thirdparty
import sys
import os.path
import imp
#TODO: 3.0 importlib.util abstract base classes could greatly simplify this code or make it prettier.
class Importer(object):
def __init__(self, path_entry):
if not path_entry.startswith(os.path.join(os.path.dirname(__file__), 'thirdparty')):
raise ImportError('Custom importer only for thirdparty objects')
self._importTuples = {}
def find_module(self, fullname):
module = fullname.rpartition('.')[2]
try:
if fullname not in self._importTuples:
fileObj, self._importTuples[fullname] = imp.find_module(module)
if isinstance(fileObj, file):
fileObj.close()
except:
print 'backup'
path = os.path.join(os.path.join(os.path.dirname(__file__), 'thirdparty'), module+'.py')
if not os.path.isfile(path):
return None
raise ImportError("Could not find dummy class for %s (%s)\n(searched:%s)" % (module, fullname, path))
self._importTuples[fullname] = path, ('.py', 'r', imp.PY_SOURCE)
return self
def load_module(self, fullname):
fp = None
python = False
print fullname
if self._importTuples[fullname][1][2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.PY_FROZEN):
fp = open( self._importTuples[fullname][0], self._importTuples[fullname][1][1])
python = True
try:
imp.load_module(fullname, fp, *self._importTuples[fullname])
finally:
if python:
module = fullname.rpartition('.')[2]
#setattr(sys.modules[fullname], module, getattr(sys.modules[fullname], module))
#sys.modules[fullname] = getattr(sys.modules[fullname], module)
if isinstance(fp, file):
fp.close()
return getattr(sys.modules[fullname], module)
sys.path_hooks.append(Importer)
【问题讨论】:
-
from ourlib.thirdparty import foo as foo? -
ourlib.thirdparty是什么?是你写的模拟python代码,还是java代码? -
您需要
ourlib.thirdparty的其他课程吗?您的第三段有点模棱两可。 -
@PierreGM
as foo对from ... import foo来说肯定是多余的吗?它已经在foo的命名空间中。 -
@PierreGM:应该是
from ourlib.thirdparty.foo import foo,我们想做from ourlib.thirparty import foo