一个简单的库,允许简单的包/模块级内省
module-discovery-utils的Python项目详细描述
模块发现实用程序
动机
一个简单的库,使动态查找和发现预定义包集中的对象更加容易。
python中经常使用这样一种模式:定义一个对象的子类,而通过作为子类的virtual,这些对象可以直接或间接地添加到注册表中。
例如烧瓶路由和sqlalchemy表。
这一切都很好,但问题是,您需要导入这些模块来注册它们。一个常见的解决方案是创建一个排序的注册表文件,有时在init.py文件中。
通常,您有大量的类,并且经常添加新的类或删除旧的类。但是,维护一个可以导入所有文件的文件可能会很麻烦,而且会与python样式的规则和格式化工具产生冲突,因为从技术上讲,这些导入不在注册表文件中使用。
因此,使用python的importlib、pkgutils和内省工具,有很多方法可以动态扫描包、加载所有子模块和解析感兴趣的对象。
我已经多次实现并重新实现了这种代码,我希望将来可以阻止其他人也这样做。
用法
递归导入一组包中的所有模块:
frommodule_discovery_utilsimportload_all_modules_in_packagesfromblahimportpackage,package2load_all_modules_in_packages(package)load_all_modules_in_packages(package2)
或
frommodule_discovery_utilsimportload_all_modules_in_packagesfromblahimportpackage,package2load_all_modules_in_packages([package,package2])
要查找包中的所有子类:
frommodule_discovery_utilsimportfind_subclasses_in_packagesfromblahimportpackage,package2,BaseClass1,BaseClass2find_subclasses_in_packages([package,package2],[BaseClass1,BaseClass2])
技术上也可以这样做:
frommodule_discovery_utilsimportload_all_modules_in_packagesfromblahimportpackage,package2,BaseClassload_all_modules_in_packages([package,package2])subclasses=BaseClass.__subclasses__()
但是,这个解决方案的问题是,在某些情况下(比如测试),您可能不想检索所有定义的子类。
在python程序中控制导入的内容实际上是不可能的,而且您不希望潜在地依赖导入顺序,或者从程序的其他部分导入来确定在任何给定时间哪些子类是“可见的”。
要查找给定包集中给定基类的所有实例:
frommodule_discovery_utilsimportfind_instances_in_packagesfromblahimportpackage,package2,BaseClass1,BaseClass2find_instances_in_packages([package,package2],[BaseClass1,BaseClass2])