关于python中的元类


# -*- coding: utf-8 -*-
class Field(object):
    #初始化两个参数,要给为name(存储的名字吗?),另一个为column_type(存储的类型吗?)
    def __init__(self, name, column_type):
        self.name = name
        self.column_type = column_type
    #print的对象,返回的是<类名:存储类型的名字>
    def __str__(self):
        return '<%s:%s>' % (self.__class__.__name__, self.name)

class StringField(Field):
    def __init__(self, name):
        super(StringField,self).__init__(name,'varchar(100)')

class IntegerField(Field):
    def __init__(self, name):
        super(IntegerField, self).__init__(name, 'bigint')

class ModelMetaclass(type):
    def __new__(cls, name, bases, attrs):
        #这个第一个判断语句的作用是什么?当创建一个类的名字为Model的时候,直接返回该类吗?没有特定的有效的作用?
        # print("cls.__name__",cls.__name__)#注意,这个cls指的是这个ModelMetaclass自己
        print("cls=>",cls.__name__)
        print("attrs:",attrs)#注意,这个attrs仅仅返回自己的属性或者方法,其中是不包含父类的。
        if name == 'Model':
            return type.__new__(cls, name, bases, attrs)
        #打印创建类的类名
        print('Found model: %s' % name)
        #创建一个字典mappings,用来存储属性属于
        mappings = dict()
        #遍历所有初始化的时候传入的属性?
        for k, v in attrs.items():
            #如果传入的键值对中,有的值是为Field的实例,例如Field,StringField,IntegerField,那么将其添加到mappings字典中去
            if isinstance(v, Field):
                print('Found mapping: %s ==> %s' % (k, v))
                mappings[k] = v
        #对于值属于Field的键值对,从attrs中删除
        for k in mappings.keys():
            attrs.pop(k)
        attrs['__mappings__'] = mappings  # 保存属性和列的映射关系
        attrs['__table__'] = name  # 假设表名和类名一致
        # print("after processed:",attrs)
        return type.__new__(cls, name, bases, attrs)

class Model(dict, metaclass=ModelMetaclass):
    def __init__(self, **kwarg):
        print("kwargs:",kwarg)
        super(Model, self).__init__(**kwarg)

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError("'Model' object has no attribute '%s'" % key)

    def __setattr__(self, key, value):
        self[key] = value

    # 模拟建表操作
    def save(self):
        fields = []
        args = []
        for k, v in self.__mappings__.items():
            fields.append(v.name)
            args.append(getattr(self, k, None))
        sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join([str(i) for i in args]))
        print('SQL: %s' % sql)
        print('ARGS: %s' % str(args))

#其实最重要的一点是,这个User是继承自Model的。
#那么,这个类User也是有由ModelMetaclass创建的
#这样的话,这个User里面的id,name,email,password,属性都会由ModelMetaclass的__new__(cls,name,bases,attrs)来处理
class User(Model):
    # 定义类的属性到列的映射:
    id = IntegerField('id')
    name = StringField('username')
    email = StringField('email')
    password = StringField('password')

u=User(id=1,name='Mr.Hu',email='[email protected]',password='hscxrzs1st')
u.save()
u=User(id=2,name='Mrs.Li',email='[email protected]',password='hscxrzs1st')
u.save()

猜你喜欢

转载自blog.csdn.net/hsc_1/article/details/80372672