龙空技术网

关于python元类的最全资料整理

快秃头的可口可爱 217

前言:

当前咱们对“python元类的作用”大体比较着重,姐妹们都需要学习一些“python元类的作用”的相关内容。那么小编也在网上收集了一些对于“python元类的作用””的相关资讯,希望同学们能喜欢,大家一起来学习一下吧!

python的基础知识python 中一切都是对象。(字符串 整数 元组 字典等是对象,函数、类也是对象)类是对象,那么是谁的对象?即类对象(类)是谁的对象?type函数的作用:1.调用时给参数(对象),打印出对象的类;2.手动生成类,跟class关键字作用类似python中的两个链:1.类的继承链;2.类(也是对象)的实例化链类定义的两种方式(等价)自动定义(class 关键字)

>>> class Animal(object):        '''Animal类,继承顶级类object'''        def __init__(self, name):            self.name = name        def eat(self):            pass        def go_to_vet(self):            pass            >>> class Cat(Animal):    '''Cat类,继承Animal类'''        def meow(self):            pass        def purr(self):            pass
2.手动定义(type函数)

type函数的使用:

第一个参数是一个字符串’Animal’,发送该字符串将其作为类名称,但也将type调用的结果赋给变量Animal。class关键字可以为你完成上面的操作。由于这里直接调用type,因此必须手动将结果赋给变量,就像在为其他类的新实例所做的一样。

第二个参数是只包含一个成员的元组:(object,)。这表示Animal类继承自object,与之前的类一样。需要在元组尾部加逗号,让Python解释器将其作为元组。括号在Python中有其他用处,因此对于只包含一个元素的元组需要在结尾处加逗号。

第三个参数是一个字典,定义了类的属性,等价于class代码块内缩进的代码部分。

>>> def init(self, name):        self.name = name    >>> def eat(self):        pass>>> def go_to_vet(self):        pass>>> Animal = type('Animal', (object,), {        '__doc__': 'A class representing an arbitrary animal.',         '__init__': init,         'eat': eat,          'go_to_vet': go_to_vet,    })    >>> def meow(self):    pass        >>> def purr(self):    pass>>> Cat = type('Cat', (Animal,), {        'meow': meow,         'purr': purr,         }) 
元类

类是对象,叫类对象。类对象的类叫元类。

元类的定义1.class定义(推荐方法)

>>> class Meta(type):        '''A custom metaclass that adds actual functionality.'''        def __new__(cls, name, bases, attrs):            return super(Meta, cls).__new__(cls, name, bases, attrs)1234
2.type定义(或者用type的子类定义)
>>> C = Meta('C', (object,), {})
元类的继承原则

一个类只能有一个元类。冲突时,有以下规则:

1.如果一个类的多个子类有不同的元类,Python的解释器会通过检查元类的起源来解决该冲突,如果其元类关系为直接继承,则最终使用子类。

>>> class Z(C, N):        pass>>> type(Z)<class '__main__.Meta'>12345
2.如果两个元类中的一个并不是另一个的直接子类,Python解释器并不知道该如何解决,因此会拒绝尝试执行(报错)
>>> class OtherMeta(type):        def __new__(cls, name, bases, attrs):            return super(OtherMeta, cls).__new__(cls, name, bases, attrs)    >>> OtherC = OtherMeta('OtherC', (object,), {})>>> class Invalid(C, OtherC):        passTraceback (most recent call last):  File "<pyshell#36>", line 1, in <module>    class Invalid(C, OtherC):TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
元类的使用语法1.Python3
>>> class C(metaclass = Meta):        pass12
2.Python2
>>> class C(object,metaclass = Meta):        pass12
3.兼容Python2和Python3
import sixclass C(six.with_metaclass(Meta)):    pass123import six@six.add_metaclass(Meta)class C(object):    pass
元类的用途

元类的主要用途是手动创建类,即在类产生前做一些工作。最常见的应用场景是ORM模型。ORM中,表是类,字段是属性,记录是对象。那么,不同表的字段不同,即不同类的属性是不同的;但是每个表都有CURD(增删改查)操作。思路来了,那就是在类产生的过程中做手脚,不同类产生不同的属性,所以手动创建类就派上用场了。代码如下:

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)class Model(dict, metaclass=ModelMetaclass):    '''模型类'''    def __init__(self, **kw):        super(Model, self).__init__(**kw)    def __getattr__(self, key):        try:            return self[key]        except KeyError:            raise AttributeError(r"'Model' object has no attribute '%s'" % key)    def __setattr__(self, key, value):        self[key] = value    def save(self):        fields = []        params = []        args = []        for k, v in self.__mappings__.items():            fields.append(v.name)            params.append('?')            args.append(getattr(self, k, None))        sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))        print('SQL: %s' % sql)        print('ARGS: %s' % str(args))class User(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()

今天要说的python篇暂时先说这么多,了解更多技术干货,关注公众号【乐字节发送123可领取相关资料】,我是哩哩,一个有趣的灵魂!下期见

标签: #python元类的作用