1

私は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などとの相対的なインポートのように見えることに注意してください

4

1 に答える 1

1

これを修正することになったのは、 futureabsolute_pathからのインポートでした。Python 2.7.3ではデフォルトですでにアクティブになっていると思いましたが、間違っていたと思います。

from __future__ import absolute_path
于 2012-10-19T15:23:22.443 に答える