Python 动态导入类或py文件,自动加载类,自动注册类

动态加载py文件中的类

开发过程中有很多需要动态的导入py文件中的类,有点类似与java的反射。
本代码样例是自动加载child_module文件夹下面的所有包含TypeA字样的类,并返回类中的name和类对象的dict

创建文件夹(文件和文件夹一览)

test_aotu_import(文件夹)
-main.py
-child_module(文件夹)
--__init__.py
--sub_class_1.py
--sub_class_2.py

主文件夹下包含main.py和child_module文件夹,然后child_module文件夹下包含init.py、sub_class_1.py、sub_class_2.py。

main.py

import pkgutil
import os 

def find_database_access_class(
    parent_module_name : str ,
    module_dir : str,
    sub_class :str = "TypeA" 
    ) -> dict:
    """
    查找moduel_dir下的所有py文件的所有类,过滤非
    参数:
        parent_module_name:父模块路径
        module_dir:需要导入的模块名称(就是需要查找子类文件的文件夹)
        sub_class:校验类的名字中是否包含TypeA字样
    返回:
        {
            "类name: 类对象
        }
    """
    base_dir = os.path.dirname(__file__)
    #如果是main执行上面的os.path.dirname,返回的是空,则需要调用abspath获取绝对路径
    if not base_dir:
        base_dir = os.path.dirname(os.path.abspath(__file__))
    modules = pkgutil.iter_modules([base_dir+"/"+module_dir])
    found_modules = []
    for x, sub_file_name, _ in modules:
        module_name = parent_module_name + "." + sub_file_name
        found_module = x.find_module(module_name).load_module(module_name)
        found_modules.append(found_module)

    found_type_a_modules = {}
    for module in found_modules:
        attrs = list(dir(module))
        #校验其类名是否包含TypeA
        type_a_class = [ x for x in attrs if sub_class in x ] 
        for class_name in type_a_class:
            class_ins = getattr(module, class_name)
            #校验类中是否包含类name变量
            if hasattr(class_ins, "name"):   
                found_type_a_modules[getattr(class_ins, "name")] = class_ins      
    return found_type_a_modules

if __name__=="__main__":
    found_class_dict = find_database_access_class("child_module", "child_module")
    for class_name, class_ in found_class_dict.items():
        print(f"class_name:{class_name}", class_().say())

child_module->sub_class_1.py

class ATypeA:

    name = "ATypeA"

    def say(self):
        return " I'm ATypeA"


class BTypeB:

    name = "BTypeB"

    def say(self):
        return " I'm BTypeB"

class CTypeA:

    name = "CTypeA"
    
    def say(self):
        return "I'm CTypeA"

child_module->sub_class_2.py

class DTypeA:

    name = "DTypeA"

    def say(self):
        return " I'm DTypeA on sub_class_2"

运行效果:

class_name:ATypeA  I'm ATypeA
class_name:CTypeA I'm CTypeA
class_name:DTypeA  I'm DTypeA on sub_class_2
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。