サードパーティのアプリケーションで jython を使用しています。サードパーティのアプリケーションには、いくつかの組み込みライブラリがありますfoo
。いくつかの (単体) テストを行うために、アプリケーションの外部でいくつかのコードを実行したいと考えています。はアプリケーションにバインドされているためfoo
、独自のモック実装を作成することにしました。
ただし、問題が 1 つあります。クラスが Java にあるのに、モック クラスを Python に実装しました。したがって、彼らのコードを使用するにはimport foo
、 foo がその後のモッククラスです。ただし、このように python モジュールをインポートすると、モジュールが名前に関連付けられているfoo.foo
ため、クラスにアクセスするために記述する必要があります。
便宜上、-class にバインドするように記述できるようにしたいと考えfrom ourlib.thirdparty import foo
てfoo
います。ただし、各ファイルの読み込みにはかなりの時間がかかるため、すべてのクラスを直接インポートすることは避けたいと思います。foo
ourlib.thirdparty
Pythonでこれを行う方法はありますか? load_module
(私は単にクラスを返すか、私が書いたものを上書きしようとしたインポートフックではうまくいきませんでしたsys.modules
(私は両方のアプローチが醜い、特に後者だと思います))
編集:
わかりました: ここでは、私たちの lib. 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)