2015-02-06 86 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