2013-01-05 40 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] 
相關問題