私はPythonモジュールのそれほど標準的ではないインポートを行っています。http / ssh / svn / etcを介してモジュールをインポートするなどの操作を行うために、ファインダーオブジェクトをsys.meta_pathに追加しています。次のようなコードを使用して、モジュールを正常にインポートできます。
def load_module(self, fullname, some_path=None):
"""
fullname is something like: this.is.a.module
"""
is_package = figure_out_if_this_is_a_package(fullname)
file_contents = get_file_contents(fullname) # via http/ssh/svn, whatever
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = "<MyFancyMagicImporter>"
mod.__loader__ = self
if is_package:
mod.__path__ = []
mod.__package__ = fullname
else:
mod.__package__ = fullname.rpartition(".")[0]
exec(file_contents, mod.__dict__)
return mod
この問題は、動的にインポートされたモジュール(これを呼びましょssh.test_module
う)が何かをインポートしようとしたときに発生します。ssh.test_module
がのようなことをする場合、import os
実際にはのような相対的なインポートを行おうとすることになりますimport ssh.test_module.os
。この相対的なインポートが失敗した場合、インポートは完全に失敗します。
ヘルプ?
更新:ところで、私はpython2.7を使用しています
更新これは私が抱えている問題を示すより良い例です:
#!/usr/bin/env python
import sys
import imp
class Loader(object):
def load_module(self, fullname, some_path=None):
file_contents = ""
if fullname == "loader_testing":
file_contents = "import os"
elif fullname == "loader_testing.blah":
file_contents = "import sys\nimport os\nimport loader_testing.halb"
elif fullname == "loader_testing.halb":
file_contents = "print('HALBHALBHALB')"
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = "<%s>" % self.__class__.__name__
mod.__loader__ = self
is_package = fullname.count(".") == 0
if is_package:
mod.__path__ = []
mod.__package__ = fullname
else:
mod.__package__ = fullname.rpartition('.')[0]
mod.__path__ = []
exec(file_contents, mod.__dict__)
return mod
def find_module(self, fullname, path=None):
if fullname.find("loader_testing") == 0:
print "loader_testing, fullname: %s" % fullname
return self
return None
sys.meta_path.append(Loader())
import loader_testing.blah
私は上記のコードが次のようなものを出力することを期待します:
loader_testing, fullname: loader_testing
loader_testing, fullname: loader_testing.blah
loader_testing, fullname: loader_testing.halb
HALBHALBHALB
代わりに、次のようになります。
loader_testing, fullname: loader_testing
loader_testing, fullname: loader_testing.os
loader_testing, fullname: loader_testing.blah
loader_testing, fullname: loader_testing.sys
loader_testing, fullname: loader_testing.loader_testing
loader_testing, fullname: loader_testing.loader_testing.halb
loader_testing.loader_testing.halb
などとの相対的なインポートのように見えることに注意してください