Python之难点元类|一句话给你安排的明明白白

type生元类,元类生类,类生对象换句话就是道系元类解读,生就完了话不多说上代码来理解:deffn1(self,name='world'):print('Hello,%s'%name)deffn2(self,name='world'):print('Hi,%s'%name)Hello=type('Hello',(object,),dict(say_hi=fn1,hi='hello'))Hi=typ...

Python之难点元类|一句话给你安排的明明白白

type生元类,元类生类,类生对象

换句话就是

道系元类解读,生就完了

话不多说上代码来理解:

def fn1(self,name='world'): print('Hello,%s'%name)def fn2(self,name='world'): print('Hi,%s'%name)Hello = type('Hello',(object,),dict(say_hi=fn1,hi='hello'))Hi = type('Hello',(object,),dict(say_hi=fn2,hi='hi'))# 生成Hello类的对象hello1 = Hello()hello1.say_hi()print(hello1.hi)print(hello1)print('-'*50) # 华丽分割线
# 生成Hi类的对象hello2 = Hi()print(hello2.hi)hello2.say_hi()print(hello2)

结果:

Hello,worldhello<__main__.Hello object at 0x0000022EBA06EBA8>--------------------------------------------------hiHi,world<__main__.Hello object at 0x0000022EBA06EC50>

type()可以产生类,那么结果就证明了,他可以定制类的名称属性方法等。可以用于创造万物。

django中的ORM,大致思路如下:

class Field(object): def __init__(self, column_type, primary_key, default):  self.column_type = column_type  self.primary_key = primary_key  self.default = defaultclass StringField(Field): def __init__(self, column_type='varchar(32)', primary_key=False, default=None):  super().__init__(column_type, primary_key, default)class IntegerField(Field): def __init__(self,column_type='int', primary_key=False, default=0):  super().__init__(column_type, primary_key, default)class MyMetaClass(type): def __new__(cls, class_name,class_bases,class_attrs):  if class_name == 'Models':return type.__new__(cls,class_name,class_bases,class_attrs)  table_name = class_attrs.get('table_name',class_name)  primary_key = None  mappings = {}  for k,v in class_attrs.items():if isinstance(v,Field): mappings[k]=v if v.primary_key:  if primary_key:raise TypeError('一张表只能有一个主键')  primary_key = k  print(class_attrs)  for k in mappings.keys():class_attrs.pop(k)  if not primary_key:raise TypeError('一张表必须有主键')  class_attrs['table_name'] = table_name  class_attrs['primary_key'] = primary_key  class_attrs['mappings'] = mappings  print(class_attrs)  return type.__new__(cls, class_name,class_bases,class_attrs)class Models(dict,metaclass=MyMetaClass): def __init__(self,**kwargs):  super().__init__(**kwargs) def __getattr__(self, item):  return self.get(item,'没有该键') def __setattr__(self, key, value):  self[key] = value @classmethod def select(cls,**kwargs):  passif __name__ == '__main__': class Teacher(Models):  table_name = 'author'  id = IntegerField(primary_key=True)  name = StringField() a = Teacher(id=12,name='xxx') print(a) print(a.name)

结果:

{'__module__': '__main__', '__qualname__': 'Teacher', 'table_name': 'author', 'id': <__main__.IntegerField object at 0x0000021E7680ECF8>, 'name': <__main__.StringField object at 0x0000021E76814438>}{'__module__': '__main__', '__qualname__': 'Teacher', 'table_name': 'author', 'primary_key': 'id', 'mappings': {'id': <__main__.IntegerField object at 0x0000021E7680ECF8>, 'name': <__main__.StringField object at 0x0000021E76814438>}}{'id': 12, 'name': 'xxx'}xxx

可以理解为:元类metaclass,是继承了type来控制其他类的产生的工具

然后用MyMetaClass来控制继承Model类的Teacher类,在生成类的实例的过程中,将类的同名属性id、name打包进mappings属性中,使得可以通过getattr来获取他自身字典中的值。可能还是不太明白那就继续看:

class Models(dict): def __init__(self,**kwargs):  super().__init__(**kwargs) def __getattr__(self, item):  return self.get(item,'没有该键') def __setattr__(self, key, value):  self[key] = value @classmethod def select(cls,**kwargs):  passif __name__ == '
源文地址:https://www.guoxiongfei.cn/cntech/18378.html