python-元编程

来源:互联网 发布:a算法解决八数码问题 编辑:程序博客网 时间:2024/06/03 18:45
  • 定义:用元类进行编程,元类→类→对象,元类比类更抽象,生成类的类
    元类定义的都是类的方法,类定义的都是实例方法

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__ = RegisterClassesclass Round(shape):passclass Square(shape):passclass 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):    passclass B(A):    __metaclass__ = finalprint(B.__class__)print(instance(B,final))#以下将会报错,因为c的bases含有B为finalclass 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,abstractmethodclass MyAbstractClass2(object):    __metaclass__ = ABCMeta    @abstractmethod    def method1(self):        pass    

例子

from abc import ABCMeta,abstractmethodclass MyAbstractClass1(object):    def method1(self):raise NotImplementedError("Please implement this method")class MyAbstractClass2(object):    __metaclass__ = ABCMeta    @abstractmethod    def method1(self):passclass Myclass1(MyAbstractClass1):    passclass Myclass2(MyAbstractClass2):    passclass Myclass3(MyAbstractClass2):    def method1(self):passa1 = 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()
原创粉丝点击