Discuss / Python / 这个有点类似java里面的反射

这个有点类似java里面的反射

Topic source
# 装饰器,用来绑定表名
def table(name):
    def wrap(cls):
        cls.__table__ = name
        return cls

    return wrap


# 字段
class Field(object):
    def __init__(self, name):
        self.name = name


class ModelMetaClass(type):
    def __new__(cls, name, bases, attrs):
        # 基类不处理
        if name == "Model":
            return type.__new__(cls, name, bases, attrs)
        # 设置映射关系表
        mappings = {}
        for key, value in attrs.items():
            if isinstance(value, Field):
                mappings[key] = value.name
        attrs["__mappings__"] = mappings
        # 表名,如果没有被装饰,则使用类名小写
        if not attrs.get("__table__"):
            attrs["__table__"] = name.lower()
        # 删除原有的字段
        for key in mappings.keys():
            attrs.pop(key)

        return type.__new__(cls, name, bases, attrs)


class Model(metaclass=ModelMetaClass):
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)


# 子类没有指定metaclass时使用父类的metaclass,父类也没有则使用type
@table("u_user")
class User(Model):
    # 使用元类创建关联映射
    id = Field("u_id")
    username = Field("u_username")
    password = Field("u_password")

    def save(self):
        # 拼接sql
        fields = []
        places = []
        values = []
        for key, value in self.__mappings__.items():
            fields.append("`%s`" % str(value))
            # places.append("%s")
            places.append("%(" + "%s" % key + ")s")
            values.append(getattr(self, key))
        sql = "insert into `%s` (%s) values (%s)" % (self.__table__, ", ".join(fields), ", ".join(places))
        arg = tuple(values)
        print(sql)
        print(arg)


if __name__ == '__main__':
    user = User(id=1, username="jack", password="12345678")
    user.save()

  • 1

Reply