python中的元类浅析
本文主要参考 刘羽冲 的文章,原文地址 点击链接, 原文讲的很生动,我这篇主要做笔记。
1 python的类型衍生
1 type: python所有类型的起源
2 元类 metaclass: 生成类的父
3 类 class: 生成实例的父
4 实例 instance: 对象实例
5 各种方法属性
2 两种创建类的方式
# 第一种方式 class Foo(object): def add_one(self, x): return x+1 print Foo().add_one(1) # out: 2
# 第二种方式 Foo = type('Foo', (object,), dict(add_one=lambda self, x: x+1)) print Foo().add_one(1) # out: 2
第一种创建方式是: 类---->实例--->方法
第二种创建方式是:type---->类---->实例--->方法
现在我们来看第二种 type方式,这里面有三个参数分别是 类名;继承的父类;类方法。
其实这三个参数也可以叫,我是谁,我从哪里来,我要干什么。
3 元类metaclass
元类更像是“天赋”。由元类创建出的类可以继承这种天赋。
如果说类是决定对象的,那么元类就是决定类的
# 由type创建元类,必须要继承type class MetaClassFoo(type): # 由元类创建类也遵循 名字;继承;方法 def __new__(cls, name, base, attrs): # 天赋,赋予给通过该元类创建的类 attrs['func'] = lambda self: 'im %s and i have func!' % self.name return type.__new__(cls, name, base, attrs) # 由元类创建类 class Foo(object): __metaclass__ = MetaClassFoo def __init__(self): self.name = 'WWW' # 由类创建实例,并生成方法 print Foo().func() # out: im WWWand i have func!
4 元类的适用场合
大部分场合不需要用元类。
元类主要适用在框架的编写,比如ORM对象关系映射。下面是一个ORM示例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 该类是定义数据类型类型的父类 class Field(object): def __init__(self, name, column_type): self.name = name self.column_type = column_type 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): if name == 'Model': return type.__new__(cls, name, bases, attrs) print('Found model: %s' % name) mappings = dict() for k, v in attrs.items(): if isinstance(v, Field): print('Found mapping: %s ==> %s' % (k, v)) mappings[k] = v for k in mappings.keys(): attrs.pop(k) attrs['__mappings__'] = mappings # 保存属性和列的映射关系 attrs['__table__'] = name # 假设表名和类名一致 return type.__new__(cls, name, bases, attrs) # 创建Model类 class Model(dict): __metaclass__ = ModelMetaclass def __init__(self, **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)) # 继承Model类的表类 class User(Model): # 定义类的属性到列的映射: id = IntegerField('id') name = StringField('username') email = StringField('email') password = StringField('password') # 表对象 u = User(id=12345, name='Batman', email='batman@nasa.org', password='iamback') u.save()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# out Found model: User Found mapping: email ==> <StringField:email> Found mapping: password ==> <StringField:password> Found mapping: id ==> <IntegerField:id> Found mapping: name ==> <StringField:username> SQL: insert into User (password,email,username,id) values (iamback,batman@nasa.org,Batman,12345) ARGS: ['iamback', 'batman@nasa.org', 'Batman', 12345]