Discuss / Python / 第二个理解起来有点困难 来加个注释

第二个理解起来有点困难 来加个注释

Topic source

枫-落J

#1 Created at ... [Delete] [Delete and Lock User]
class ModelMetaclass(type):

    def __new__(cls, name, bases, attrs):
        if name=='Model'://如果当前创建对象为Model的实例则不做操作(因为Model没有属性 做了也白做)
            return type.__new__(cls, name, bases, attrs)
        print('Found model: %s' % name)//打印当前实例的类名称
        mappings = dict()//创建一个空的字典
        for k, v in attrs.items():
        //attrs应该是存放了类的所有属性以及方法的字典,我的理解是在python中一切都是对象. 方法的类型为<class 'function'> 值为形如<function aaa at 0x10e4839d8>的内存地址.可以理解为方法是一个function的实例.这里k是属性或方法的类型,v是属性或方法的值
            if isinstance(v, Field)://如果v是Field的实例对象
                print('Found mapping: %s ==> %s' % (k, v))
                mappings[k] = v//将其添加到mappings字典中
        for k in mappings.keys()://最后遍历mappings,从attrs中pop
            attrs.pop(k)
        //最后正在创建的对象 添加两个属性  __mappings__和 __table__
        attrs['__mappings__'] = mappings # 保存属性和列的映射关系
        attrs['__table__'] = name # 假设表名和类名一致
        return type.__new__(cls, name, bases, attrs)

枫-落J

#2 Created at ... [Delete] [Delete and Lock User]
class ModelMetaclass(type):
    def __new__(cls, name, bases, attrs):
        for k, v in attrs.items():
            print('key:%s,value:%s' % (k, v))
        return type.__new__(cls, name, bases, attrs)


class Test(object, metaclass=ModelMetaclass):
    name = "dlj"
    age = 123

    def aaa(self):
        pass


a = Test()

打印结果:
key:name,value:dlj
key:__module__,value:__main__
key:aaa,value:<function Test.aaa at 0x109fa10d0>
key:age,value:123
key:__qualname__,value:Test

验证了attrs是包含所有元素和方法的字典

追思旅123

#3 Created at ... [Delete] [Delete and Lock User]

class User(Model):

# 定义类的属性到列的映射:
id = IntegerField('id')
name = StringField('username')
email = StringField('email')
password = StringField('password')

如果把id,username,email,password初始化将毫无意义 ,如果是这样当时new一个user时无需pop了 只需将id,name,email,password名字更改一下即可,应为这几个字段不是表示的是表的字段名,所以这个User的类建议修改 class User(Model):

# 定义类的属性到列的映射:
id = IntegerField('varchar(100')
username = StringField('varchar(100')
email = StringField('varchar(100')
password = StringField('varchar(100')

然后改一下StringField(Field)的定义

其中id、username、email、password表示表的字段名

黑桃老Kei

#4 Created at ... [Delete] [Delete and Lock User]
    def __new__(cls, name, bases, attrs):
        if name=='Model'://如果当前创建对象为Model的实例则不做操作(因为Model没有属性 做了也白做)
            return type.__new__(cls, name, bases, attrs)
        print('Found model: %s' % name)//打印当前实例的类名称

这里return type.__new__(cls, name, bases, attrs)之后为什么还会去执行下面的print。。。

黑桃老Kei

#5 Created at ... [Delete] [Delete and Lock User]
    def __new__(cls, name, bases, attrs):
        if name=='Model'://如果当前创建对象为Model的实例则不做操作(因为Model没有属性 做了也白做)
            return type.__new__(cls, name, bases, attrs)
        print('Found model: %s' % name)//打印当前实例的类名称

这里return type.__new__(cls, name, bases, attrs)之后为什么还会去执行下面的print。。。

看错了 ,请忽视

dfdfdsadf

#6 Created at ... [Delete] [Delete and Lock User]

根据楼主的 __new()__方法实现的功能,进行了思考,写了一篇文章 Python类的__new()__ 方法 VS metaclass的__new()__ 方法 欢迎一起讨论。


  • 1

Reply