python 学习笔记 metaclass详解
2015-02-14 21:00
513 查看
python元类metaclass:
metaclass控制类的行为。当我们创建类的时候我们就可以通过这个类来创建对象实例,当然同样的,如果我们想要创建类,那么就必须根据这个metaclass来创建类,也就是说,我们需要先定义metaclass才能过创建类。
1:Python中类本省就是对象,类之所以为类,就是因为类这个对象本身拥有创建对象的能力。
于是我们可以对类进行1:将它赋值给一个变量,2:拷贝它,3:为它增加属性,4:作为参数进行传递。
因为类也是对象,所以我们可以在运行是动态的创建类。
当我们使用class关键字的时候,Python解释器会自动的为我们创建这个类对象,同时Python也提供手动处理是方法,这个方法就是type()。type()方法根据参数的不同有两种完全不一样的方法。1:type可以返回一个对象的类型是什么。2:type接受一个类的描述作为参数可以放回一个类。
type可以像这样进行工作:
比如:
可以这样手动创建
同样你可以为其增加属性或者方法,为其继承:
元类就是用来创建这些类的类。元类是类的类,type就是Python在背后用来创建所有类的元类。Python中所有的东西都是对象,包括整数,字符串,等等,而且他们都是由一个类创建而来的:
对于没有自定义元类的类来说,__class__属性的值都为<type'type'>.因为他们都是由元类type创建出来的。当然我们也可以自己创建元类。
__metaclass字段:我们在写一个类的时候,可以为其添加一个__metaclass__属性这样Python就会用__metaclass__指定的元类来创建这个类。
首先Python会在类的定义中寻找__metaclass__属性,如果没有找到,则会用内建的type元类来创建这个类,否则用指定的元类来创建这个类。之后类对象才会在内存中创建。
元类的主要目的是为了在创建类的时候能够自动的改变类。一般在代码中metaclass类如下:
这样Python解释器在创建类Mylist的时候发现其有__metaclass__属性并且只为ListMetaclass于是用ListMetaclass这个元类来创建Mylist类。可以看到ListMetaclass这个元类继承了type类并且重写了__new__方法,其有四个属性,但是type方法只有三个属性,这个很好理解:就像类中每个方法都会有一个self一样,cls通用表示元类对象自身,
name:表示要创建的类名
bases:表示父类tuple
attr:表示属性,方法dict
所谓存在即为合理,orm关系模型就会用到动态修改类定义的方式,也就是元类。例如一下就是一个简单的orm框架
编写底层模块的第一步,就是先把调用接口写出来,比如想要定义一个User类来操作对应的数据库表User我们希望这样写:
其中,父类Model和属性类型StringFieldIntegerField是又ORM框架提供,剩下的方法都是由metaclass完成。
首先定义field类负责保存数据库表的字段名和字段类型:
在field基础上编写StringFieldIntegerField等等
然后就是modelMetaclass了
以上就实现了一个简单的orm模块
metaclass控制类的行为。当我们创建类的时候我们就可以通过这个类来创建对象实例,当然同样的,如果我们想要创建类,那么就必须根据这个metaclass来创建类,也就是说,我们需要先定义metaclass才能过创建类。
1:Python中类本省就是对象,类之所以为类,就是因为类这个对象本身拥有创建对象的能力。
于是我们可以对类进行1:将它赋值给一个变量,2:拷贝它,3:为它增加属性,4:作为参数进行传递。
因为类也是对象,所以我们可以在运行是动态的创建类。
defmake_class():
classFoo(object):
pass
returnFoo
myclass=make_class()
printmyclass
#<class'__main__'.Foo>
当我们使用class关键字的时候,Python解释器会自动的为我们创建这个类对象,同时Python也提供手动处理是方法,这个方法就是type()。type()方法根据参数的不同有两种完全不一样的方法。1:type可以返回一个对象的类型是什么。2:type接受一个类的描述作为参数可以放回一个类。
>>>printtype(1)
<type'int'>
>>>printtype('1')
<type'str'>
>>>printtype(myclass)
<type'type'>
>>>printtype(myclass())
<type'__main__.myclass'>
type可以像这样进行工作:
type(类名,父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
比如:
>>>classmyclass2(object):
...pass
可以这样手动创建
>>>myclass2=type('myclass2',(),{})
>>>printmyclass2
<class'__main__.myclass2'>
>>>printmyclass2()
<__main__.myclass2objectat0x23291212>
同样你可以为其增加属性或者方法,为其继承:
>>>defecho_bar(self):
...printself.bar
>>>Foo=type('Foo',(),{'bar':True})
>>>Foo().bar
True
>>>Foo2=type('Foo2',(Foo,),{'echo_bar':echo_bar})
>>>Foo2().echo_bar()
True
元类就是用来创建这些类的类。元类是类的类,type就是Python在背后用来创建所有类的元类。Python中所有的东西都是对象,包括整数,字符串,等等,而且他们都是由一个类创建而来的:
>>>age=25
>>>age.__class__
<type'int'>
>>>name='bob'
>>>name.__class__
<type'str'>
>>>deffoo():pass
>>>foo.__class__
<type'function'>
对于没有自定义元类的类来说,__class__属性的值都为<type'type'>.因为他们都是由元类type创建出来的。当然我们也可以自己创建元类。
__metaclass字段:我们在写一个类的时候,可以为其添加一个__metaclass__属性这样Python就会用__metaclass__指定的元类来创建这个类。
classFoo(object):
__metaclass__=something
首先Python会在类的定义中寻找__metaclass__属性,如果没有找到,则会用内建的type元类来创建这个类,否则用指定的元类来创建这个类。之后类对象才会在内存中创建。
元类的主要目的是为了在创建类的时候能够自动的改变类。一般在代码中metaclass类如下:
classListMetaclass(type):
def__new__(cls,name,bases,attrs):
attr['add']=lambdaself,value:self.append(value)
returntype.__new__(cls,name,bases,attrs)
classMylist(list):
__metaclass__=ListMetaclass#指示使用ListMetaclass来创建类
这样Python解释器在创建类Mylist的时候发现其有__metaclass__属性并且只为ListMetaclass于是用ListMetaclass这个元类来创建Mylist类。可以看到ListMetaclass这个元类继承了type类并且重写了__new__方法,其有四个属性,但是type方法只有三个属性,这个很好理解:就像类中每个方法都会有一个self一样,cls通用表示元类对象自身,
name:表示要创建的类名
bases:表示父类tuple
attr:表示属性,方法dict
所谓存在即为合理,orm关系模型就会用到动态修改类定义的方式,也就是元类。例如一下就是一个简单的orm框架
编写底层模块的第一步,就是先把调用接口写出来,比如想要定义一个User类来操作对应的数据库表User我们希望这样写:
classUser(Model):
#定义类的属性到列的映射
id=IntegerField('id')
name=StringField('username')
email=StringField('email')
password=StringField('password')
#创建一个实例:
u=User(id=12345,name='Michael',email='test@orm.org',password='my-pwd')
u.save()
其中,父类Model和属性类型StringFieldIntegerField是又ORM框架提供,剩下的方法都是由metaclass完成。
首先定义field类负责保存数据库表的字段名和字段类型:
classField(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)
#__str__相当于java中的tostring方法self.__class__返回创建这个对象的类
在field基础上编写StringFieldIntegerField等等
classStringField(Field):
def__init__(self,name):
super(StringField,self).__init__(name,'varchar(100)')
classIntegerField(Field):
def__init__(self,name):
super(IntegerField,self).__init__(name,'bigint')
然后就是modelMetaclass了
classModelMetaclass(type):
def__new__(cls,name,bases,attrs):
ifname=='Model':
returntype.__new__(cls,name,bases,attrs)#不对Model类定义做任何修改
mappings=dict()
fork,vinattrs.iteritems():#k是属性名v是数据库列Field
ifisinstance(v,Field):
print('Foundmapping:%s===>%s'%(k,v))
mappings[k]=v
forkinmappings.iterkeys():
attrs.pop(k)#从类属性中删除跟数据库对应的属性
attrs['__table__']=name#假设类名和表名一致
attrs['__mappings__']=mappings#保存属性和列的映射关系
returntype.__new__(cls,name,bases,attrs)#调用父类的__new__方法创建类对象
classModel(dict):
__metaclass__=ModelMetaclass#指明用ModelMetaclass元类来创建Model类
def__init__(self,**kw):
super(Model,self).__init__(**kw)#调用父类的方法也就是dict
def__getattr__(self,key):#model.key
try:
returnself[key]
exceptKeyError:
raiseAttributeError(r"'Model'objecthasnoattribute'%s'"%key)
def__setattr__(self,key,value):#model.key=value
self[key]=value
defsave(self):
fields=[]
params=[]
args=[]
fork,vinself.__mappings__.iteritems():#保存属性和列的对应关系
fields.append(v.name)#列名
params.append('?')
args.append(getattr(self,k,None))#如果不存在返回None
sql='insertinto%s(%s)values(%s)'%(self.__table__,','.join(fields),','.join(params))
print('SQL:%s'%sql)
print('ARGS:%s'%str(args))
以上就实现了一个简单的orm模块
相关文章推荐
- python学习笔记1-元类__metaclass__
- python 学习笔记——python metaclass 元类
- python学习笔记:字典的使用示例详解
- Python学习笔记5:函数参数详解
- python入门笔记(Day7)--slots,@property,MixIn,定制(str,iter,getitem,getattr,call)枚举(Enum)元type,metaclass,ORM
- python开发技术详解的学习笔记
- python 学习笔记十四 jQuery案例详解(进阶篇)
- python学习笔记:字典的使用示例详解
- python笔记:深刻理解Python中的元类(metaclass)
- Python学习笔记:详解random模块和time模块
- 详解python单例模式与metaclass
- python学习笔记 class
- 十五、python class 类学习笔记
- Python学习笔记(8)class, for loop, while loop, spaceship project
- 「学习笔记——Python」Google's Python Class 学习笔记
- Python开发技术详解 学习笔记
- Python学习笔记 装饰器详解
- Python 单例模式详解 __new__, import ,__dict__,__metaclass__
- Python学习笔记:魔术方法详解
- Python学习笔记:类(class)