添加动态类进行继承和类名映射

问题描述 投票:0回答:1

我正在开发一个 Python 项目,其中有两个不同的对象文档映射器 (ODM):Beanie 和 Bunnet,用于管理数据库中的数据。每个 ODM 都需要不同的类结构来定义数据模型。

我有两个单独的用户模型类,用于 Bunnet 的 User_B1 和用于 Beanie 的 User_B2,它们都继承自各自 ODM 的基本文档类。

现在,我正在构建一个数据库类,该类根据用户在运行时对 ODM 的选择动态选择适当的用户类。我目前正在使用字典(映射)将类名映射到相应的类,并使用 call 方法根据其名称返回所需的类实例。

class User_B1(UserModel, BunnetDocument):
    class Settings:
        name = "user"

class User_B2(UserModel, BeanieDocument):
    class Settings:
        name = "user"

class Database:
    def __init__(self, odm_name: str):
        if odm_name == "bunnet":
            self.User = User_B1
        elif odm_name == "beanie":
            self.User = User_B2
        else:
            raise ValueError("Invalid ODM name")

    def __call__(self, class_name: str) -> Any:
        mapping = {"User": self.User}
        return mapping[class_name]

if __name__ == "__main__":
    db = Database("bunnet")
    user = db.User
    user = db("User") 
    obj_1 = user(
        username="ali2",
        password="Addsasad12365",
        name="ali",
        family="ali",
        email="[email protected]",
    )
    obj_1.insert()

但是,我正在寻找一种更干净、更动态的方法来实现数据库类,而不使用静态映射字典。有没有办法根据提供的类名动态返回适当的类,也许可以通过检查数据库实例中的可用类或使用其他 Pythonic 方法?

此外,我想知道是否有更好的方法来管理 User 类选择,这样我就不需要单独的 User_B1 和 User_B2 类,而是可以根据用户的ODM选择。这是否可行,还是我需要为每个 ODM 维护单独的类?

python class inheritance abstract-class abstract
1个回答
0
投票

根据提供的类名动态返回合适的类,可以使用内置的 getattr() 函数从模块命名空间获取类对象。

class Database:
    def __init__(self, odm_name: str):
        if odm_name == "bunnet":
            self.module = "bunnet_module"
        elif odm_name == "beanie":
            self.module = "beanie_module"
        else:
            raise ValueError("Invalid ODM name")

    def __call__(self, class_name: str) -> Any:
        module = importlib.import_module(self.module)
        return getattr(module, class_name)

用户类别选择的管理允许根据用户的ODM选择动态切换用户的父类别。一种方法是建立一个包含公共属性和功能的基本 User 类,然后定义继承自 User 基类和相应 ODM 文档基类的各个 ODM 子类。以下是如何更改用户类以利用基本用户类:

class User(UserModel):
    class Settings:
        name = "user"

    def common_method(self):
        pass

class User_B1(User, BunnetDocument):
    pass

class User_B2(User, BeanieDocument):
    pass
© www.soinside.com 2019 - 2024. All rights reserved.