我在第三方應用程序中使用jython。第三方應用程序有一些內置庫foo
。爲了做一些(單元)測試,我們希望在應用程序之外運行一些代碼。由於foo
被綁定到應用程序,我們決定編寫我們自己的模擬實現。如何更改導入庫的名稱?
但是有一個問題,我們在python中實現了我們的模擬類,而他們的類是在java中。因此,爲了使用他們的代碼,人們會做import foo
,並且之後foo是模擬類。但是,如果我們像這樣導入python模塊,我們將模塊附加到名稱上,因此必須編寫foo.foo
才能進入該類。
爲了方便的原因,我們很樂意能寫from ourlib.thirdparty import foo
綁定foo
到foo
- 類。但是我們希望避免直接導入ourlib.thirdparty
中的所有類,因爲每個文件的加載時間需要相當長的一段時間。
有什麼辦法可以在python中做到這一點? (我沒有導入掛鉤跑遠我想簡單地從load_module
返回類或覆蓋了我寫sys.modules
(我認爲這兩種方法都是醜陋的,尤其是後來))
編輯:
OK :這裏是ourlib.thirdparty文件是什麼樣子的簡化(沒有魔法):
foo.py:
try:
import foo
except ImportError:
class foo
....
ACTU盟友他們看起來像這樣:
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)
':
所以,下面的代碼將也完全爲你工作? –
什麼是'ourlib.thirdparty'?那是你寫的模擬python代碼,還是java代碼? – mgilson
你需要'ourlib.thirdparty'中的其他類嗎?你的第三段有點含糊。 – deadly