繁体   English   中英

从目录导入模块而不触及sys.path

[英]Import module from directory without touching sys.path

我正在寻找一种从本地文件系统上的位置导入模块的方法,而无需将父目录附加到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

尝试查看imp模块。

具体来说,功能

imp. find_module ( )

imp. load_module ( )

看起来很有用

最终守则

感谢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]

我现在正在使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM