2015-02-06 132 views
2

我想放在一起將處理延遲加載的模塊,不明確存在的系統。基本上我有一個http服務器,其中有許多端點,但我並不知道我想以編程方式提供導入。這些模塊都會有一個統一的方法簽名,他們只是不會提前存在。在python中延遲加載模塊

import lazy.route as test 
import lazy.fake as test2 

test('Does this exist?') # This sends a post request. 
test2("This doesn't exist.") # Also sends a post request 

我可以處理,我需要這些進口具有均勻裝飾各地所有的邏輯,我無法找到任何方式「裝飾」進口蟒蛇,或實際上與他們在任何一種編程方式進行交互。

有沒有人有這方面的經驗?我一直在四處尋找,而我發現的最接近的東西是ast模塊,在我目前的理解下,這會導致我目前的一種非常糟糕的實現(例如查找所有導入語句並手動覆蓋導入功能)

不是在尋找講義,只是開始查看python代碼庫的一部分,或者是某人做了類似的示例。

+0

您是否在尋找['importlib'(https://docs.python.org/3/library/importlib.html)? – jonrsharpe 2015-02-06 17:27:21

+0

@jonrsharpe不,反之。我沒有嘗試在其他地方使用導入,我試圖覆蓋現有的python導入操作 – 2015-02-06 17:28:57

+0

近距離投票:不要求一個庫,主要是這個功能是否可能在Python中,因爲沒有任何我可以找到的文檔。 – 2015-02-06 17:31:47

回答

7

我在搜索結果中找到了一點聰明,並設法找到了專門解決這個問題的PEP,它恰好相對未知,可能是因爲合理使用的子集非常窄。

我發現了一段極好的示例代碼,展示了新的sys.meta_path實現。我已經在下面發佈它,以獲取有關如何動態引導您的導入語句的信息。

import sys 


class VirtualModule(object): 

    def hello(self): 
     return 'Hello World!' 


class CustomImporter(object): 

    virtual_name = 'my_virtual_module' 

    def find_module(self, fullname, path): 
     """This method is called by Python if this class 
     is on sys.path. fullname is the fully-qualified 
     name of the module to look for, and path is either 
     __path__ (for submodules and subpackages) or None (for 
     a top-level module/package). 

     Note that this method will be called every time an import 
     statement is detected (or __import__ is called), before 
     Python's built-in package/module-finding code kicks in.""" 

     if fullname == self.virtual_name: 

     # As per PEP #302 (which implemented the sys.meta_path protocol), 
     # if fullname is the name of a module/package that we want to 
     # report as found, then we need to return a loader object. 
     # In this simple example, that will just be self. 

     return self 

     # If we don't provide the requested module, return None, as per 
     # PEP #302. 

     return None 

    def load_module(self, fullname): 
     """This method is called by Python if CustomImporter.find_module 
     does not return None. fullname is the fully-qualified name 
     of the module/package that was requested.""" 

     if fullname != self.virtual_name: 
     # Raise ImportError as per PEP #302 if the requested module/package 
     # couldn't be loaded. This should never be reached in this 
     # simple example, but it's included here for completeness. :) 
     raise ImportError(fullname) 

     # PEP#302 says to return the module if the loader object (i.e, 
     # this class) successfully loaded the module. 
     # Note that a regular class works just fine as a module. 
     return VirtualModule() 


if __name__ == '__main__': 

    # Add our import hook to sys.meta_path 
    sys.meta_path.append(CustomImporter()) 

    # Let's use our import hook 
    import my_virtual_module 
    print my_virtual_module.hello() 

完整的博客文章here