前言:
当前咱们对“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): pass2.手动定义(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)12342.type定义(或者用type的子类定义)
>>> C = Meta('C', (object,), {})元类的继承原则
一个类只能有一个元类。冲突时,有以下规则:
1.如果一个类的多个子类有不同的元类,Python的解释器会通过检查元类的起源来解决该冲突,如果其元类关系为直接继承,则最终使用子类。
>>> class Z(C, N): pass>>> type(Z)<class '__main__.Meta'>123452.如果两个元类中的一个并不是另一个的直接子类,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): pass122.Python2
>>> class C(object,metaclass = Meta): pass123.兼容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元类的作用