python-元编程

  • 定义:用元类进行编程,元类→类→对象,元类比类更抽象,生成类的类
    元类定义的都是类的方法,类定义的都是实例方法

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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值