- 定义:用元类进行编程,元类→类→对象,元类比类更抽象,生成类的类
元类定义的都是类的方法,类定义的都是实例方法
type
元类type
Type(name,bases,attrs):
name:类名字符串
bases:父类元组
attrs:属性字典
A = type('A',(object,),{'b':1})
a = A()
def howdy(self,you):
print("howdy,"+you)
#通过list元类生成 Mylist 类
Mylist = type('Mylist',(list,),dict(x=12,howdy=howdy))
ml = Mylist()
ml.append('llkk')
ml.howdy("john")
用type生成元类
class SimpleMeta(type):
#由于生成的是元类,所以元类里包含的均为类方法,类方法里包含的是方法
def __init__(cls,name,bases,nmspc):
super(SimpleMeta1,cls).__init__(name,bases,nmspc)
cls.uses_metaclass = lambda self:"yes!"
A = SimpleMeta('A',(),{})
#上述等价于:通常采用下面的方式
class A(object):
__metaclass__ = SimpleMeta
元类例子
class RegisterClasses(type):
def __init__(cls,name,bases,nmspc):
super(RegisterClasses,cls).__init__(name,bases,nmspc)
if not hasattr(cls,'registry'):
cls.registry = set()
cls.registry.add(cls)
cls.registry -= set(cls)
def __iter__(cls):
return iter(cls.registry)
def __str__(cls):
if cls in cls.registry:
return cls.__name__
return cls.__name__+":"+",".join([sc.__name__ for sc in cls])
class shape(object):
__metaclass__ = RegisterClasses
class Round(shape):pass
class Square(shape):pass
class Circle(Round):pass
new
- 利用元类定义不可继承类
class final(type):
def __init__(cls,name,bases,namespace):
super(final,cls).__init__(name,bases,namespace)
for kclass in bases:
if instance(kclass,final):
raise TypeError(str(kclass.__name__)+"is final")
class A(object):
pass
class B(A):
__metaclass__ = final
print(B.__class__)
print(instance(B,final))
#以下将会报错,因为c的bases含有B为final
class C(B):
pass
- new
new与init很像,new将实例产生并分配空间,init是配置参数(执行顺序,先分配空间再配置参数)
class PositiveInt1(int):
def __init__(self,value):
super(PositiveInt1,self).__init__(self,abs(value))
class PositiveInt2(int):
def __new__(cls,value):
return super(PositiveInt2,cls).__new__(cls,abs(value))
if __name__=='__main__':
print(PositiveInt1(-3)) #显示结果为-3,init只是配置参数产生值
print(PositiveInt2(-3)) #显示结果为3
接口
- 抽象函数——虚函数,在子类里实现
class MyAbstractClass1(object):
def method1(self):
raise NotImplementedError("Please implement this method")
- 接口:由一组抽象函数组成的类
#此种方法定义的抽象类会在实例化的时候就报错
from abc import ABCMeta,abstractmethod
class MyAbstractClass2(object):
__metaclass__ = ABCMeta
@abstractmethod
def method1(self):
pass
例子
from abc import ABCMeta,abstractmethod
class MyAbstractClass1(object):
def method1(self):raise NotImplementedError("Please implement this method")
class MyAbstractClass2(object):
__metaclass__ = ABCMeta
@abstractmethod
def method1(self):pass
class Myclass1(MyAbstractClass1):
pass
class Myclass2(MyAbstractClass2):
pass
class Myclass3(MyAbstractClass2):
def method1(self):pass
a1 = Myclass1() #不报错
a1.method() #报错
a2 = Myclass2() #实例化的时候就报错,通过元类ABCMeta实现
ORM
- 对象关系映射。将数据库的操作用面向对象的程序方法实现
- Object
- Relational
- Mapping
- 优点
- 易改:便于更换数据库,sql语句是由底层根据数据库类型生成的
- 安全
- 易用:便于对数据模型进行操作,创建、更新、查询、删除。用户编写简单,无需写sql语句
- 易看:使数据模型的程序文档化,便于维护
class User(Model):
id = IntegerFiled('uid')
name = StringField('username')
email = StringFiled('email')
password = StringField('password')
u = User(id=123,name='zz',email='xx@orm.org',password='xxxx')
u.save()
例子
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386820064557c69858840b4c48d2b8411bc2ea9099ba000
' Simple ORM using metaclass '
__author__ = 'Michael Liao'
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):
print "name is ",name
print "bases is ",bases
print "attrs is ",attrs
if name=='Model':
return type.__new__(cls, name, bases, attrs)
print('Found model: %s' % name)
mappings = dict()
for k, v in attrs.iteritems():
if isinstance(v, Field):
print('Found mapping: %s ==> %s' % (k, v))
mappings[k] = v
for k in mappings.iterkeys():
attrs.pop(k)
attrs['__mappings__'] = mappings # 保存属性和列的映射关系
attrs['__table__'] = name # 假设表名和类名一致
return type.__new__(cls, name, bases, attrs)
class Model(dict):
__metaclass__ = ModelMetaclass
def __init__(self, **kw):
print "Model instance __init__"
super(Model, self).__init__(**kw)
def save(self):
fields = []
params = []
args = []
for k, v in self.__mappings__.iteritems():
fields.append(v.name)
params.append('%s')
args.append(self[k])
sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))
print('SQL: %s' % sql)
print('ARGS: %s' % str(args))
@classmethod
def find_all(cls, *args):
sql = 'select * from %s' % cls.__table__
print('SQL: %s' % sql)
# testing code:
class User(Model):
id = IntegerField('uid')
name = StringField('username')
email = StringField('email')
password = StringField('password')
u1 = User(id=12345, name='Michael', email='test1@orm.org', password='my-pwd')
u2 = User(id=22345, name='Richael', email='test2@orm.org', password='my-pwd')
u3 = User(id=32345, name='Hichael', email='test3@orm.org', password='my-pwd')
u1.save()
u2.save()
u3.save()