2013-01-05 41 views
2

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

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 
+0

如果你想添加一个答案,然后在答案,而不是一个问题,这样做。我将问题恢复到原来的形式。 –

+0

@DavidHeffernan:正确的答案是来自C0deH4cker的人。我应该在哪里放置最终代码? Imho把它变成一个新的答案没有什么意义。 –

+1

是的,它把它放在一个新的答案是完全合理的。对于未来的访问者来说,这是一段很有用的代码。你已经接受了正确的答案。添加另一个答案来提供更多的帮助是好的,并鼓励。 –

回答

3

尝试查看imp模块。

具体地,功能

imp.find_module(name[, path])

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

看是有用的。

+0

非常感谢。我编辑了这个问题以包含新的代码。 –

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] 
相关问题