3

我正在寻找一种方法来从本地文件系统上的某个位置导入模块,而无需将父目录附加到 sys.path. 这是显示所需接口的示例代码:

imp = Importer()
imp.add_path(r'C:\pylibs')
foolib = imp.import_('foolib')
print foolib
# <module 'foolib' from 'C:\pylibs\foolib.py'>

我可以想到这样的实现,但我想知道是否有可能没有sys.path临时交换变量的解决方法。

import sys

class Importer(object):

    def __init__(self):
        super(Importer, self).__init__()
        self.path = []

    def add_path(self, path):
        self.path.append(path)

    def import_(self, name):
        old_path = sys.path
        sys.path = self.path

        try:
            return __import__(name, {}, {})
        finally:
            sys.path = old_path
4

3 回答 3

3

尝试查看imp模块。

具体来说,函数

imp.find_module(name[, path])

imp.load_module(name, file, pathname, description)

看起来很有用。

于 2013-01-05T17:03:31.813 回答
1

最终代码

感谢C0deH4cker

import sys
import imp

class Importer(object):
    r"""
    Use this class to enable importing modules from specific
    directories independent from `sys.path`.
    """

    def __init__(self):
        super(Importer, self).__init__()
        self.path = []

    def add(self, *paths):
        r"""
        Add the passed strings to the search-path for importing
        modules. Raises TypeError if non-string object was passed.
        Passed paths are automatically expanded.
        """

        new_paths = []
        for path in paths:
            if not isinstance(path, basestring):
                raise TypeError('passed argument must be string.')
            path = os.path.expanduser(path)
            new_paths.append(path)

        self.path.extend(new_paths)

    def import_(self, name, load_globally=False):
        r"""
        Import the module with the given name from the directories
        added to the Importer. The loaded module will not be inserted
        into `sys.modules` unless `load_globally` is True.
        """

        prev_module = None
        if name in sys.modules and not load_globally:
            prev_module = sys.modules[name]
            del sys.modules[name]

        data = imp.find_module(name, self.path)
        try:
            return imp.load_module(name, *data)
        except:
            data[0].close()
            raise
        finally:
            # Restore the old module or remove the module that was just
            # loaded from `sys.modules` only if we do not load the module
            # globally.
            if not load_globally:
                if prev_module:
                    sys.modules[name] = prev_module
                else:
                    del sys.modules[name]
于 2013-01-06T16:41:07.793 回答
0

我现在正在使用localimport

with _localimport('lib', eggs=True) as importer:
    import some_package
assert 'some_package' not in sys.modules
assert 'some_package' in importer.modules

https://github.com/NiklasRosenstein/localimport

于 2015-04-11T19:33:01.317 回答