1.什么是类在理解元类之前,我们必须先掌握python中的类(class)。
和大多数语言一样,python中的类知识用来描述如何“生成一个对象”:
但是,在python中,类不仅能用来描述如何生成一个对象, 类本身也是对象 。
在你使用关键词** class **的时候,python就会执行它,并创建一个对象。
>> > class objectcreator(object):... pass...上述指令在内存中创建了一个“objectivecreator”的对象。
这个对象(类)本身具有创建对象(实例)的能力,因此它也是一个类。你可以对它做以下操作:
1.将其分配给变量
2.复制它
3.为其添加属性
4.将其作为函数参数传递
例如:
2.动态创建类由于类是对象,因此你可以像创建任何对象(数组、字典等)一样,随时随地创建类。
你甚至可以在函数里创建类:
但是,这样的类并不是很动态,因为你必须自己编写整个类。
使用class关键字时,python会帮你自动创建此对象,但是,python同样也提供了一种手动创建的方法,那就是type函数。
>> > print(type(1)) >> > print(type(1)) >> > print(type(objectcreator)) >> > print(type(objectcreator()))type函数最经典的用法是返回对象的类型。但是很少人知道,它还能接受参数并手动创建类。
type(name, bases, attrs)其中
name : 类名bases : 元组,父类名attrs : 字典,类属性值因此你可以这样手动创建类:
>> > myshinyclass = type('myshinyclass', (), {}) # returns a class object >> > print(myshinyclass) >> > print(myshinyclass()) # create an instance with the class如果你想给它赋予属性,可以这样玩:
>> > class foo(object):... bar = true等同于
>> > foo = type('foo', (), {'bar':true})用来继承也是可以的:
>> > foochild = type('foochild', (foo,), {}) >> > print(foochild) >> > print(foochild.bar) # bar is inherited from footrue可见通过 type() 函数创建的类和直接写class是完全一样的。
因为python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用 type() 函数创建出class。
正常情况下,我们用class来定义类,但是,type()函数也允许我们动态创建类,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同。
python是通过什么做到这一切的?那就是元类。
3.什么是元类元类就是用于创建类的“东西”。
你定义类是为了创建对象,python中所有的类都是对象。元类是用于创建这些对象的。可以看这个例子:
myclass = metaclass()my_object = myclass()这有点像套娃。这段代码转化为type就是这样的:
myclass = type('myclass', (), {})因此,我们可以得到一个基本事实,type 本身就是一个 元类 。
其实,就是 type 在幕后创建了python中所有的类。
通过检查__class__属性,你会看到python中,一切对象都是基于 type 的:
>> > age = 35 >> > age.__class__ >> > name = 'bob' >> > name.__class__ >> > def foo(): pass >> > foo.__class__ >> > class bar(object): pass >> > b = bar() >> > b.__class__那么,有个有趣的问题,__class__的__class__是什么呢?
>> > age.__class__.__class__ >> > name.__class__.__class__ >> > foo.__class__.__class__ >> > b.__class__.__class__因此,元类只是创建类对象的东西,如果愿意,可以将其称为“类的工厂”。
type 是python使用的内置元类。不过,你可以创建自己的元类。
3.1 __metaclass__属性在python 2中,可以在编写类时添加属性__metaclass__,使用某个元类来创建该类:
class foo(object): __metaclass__ = something... [...]不过要小心的是,你虽然先写了 class foo(object),但foo这个对象尚未被创建,python将先寻找__metaclass__类,找到后用它来创建foo类。
如果没有这个__metaclass__类,它将使用 type 来创建类。
因此,类创建的流程是这样的:
1.创建的类中有__metaclass__元类属性吗?
2.如果有,那就用__metaclass__给该类在内存中创建一个类对象。
3.如果python找不到__metaclass__,它将在module级别查找__metaclass__属性 。
4.如果还是没有,那就使用父类的元类来创建类对象。
现在的问题就是,你可以在__metaclass__中放置些什么代码呢?
答案就是:可以创建一个类的东西。那么什么可以用来创建一个类呢?type,或者任何继承或使用它的东西。
3.2 python 3中的元类设置元类的语法在python3已改为:
class foo(object, metaclass=something): ...即不再使用__metaclass__属性,而是在基类参数列表中引入关键字参数。
不过元类的基本工作方式不变。在python3中,你可以将属性作为关键字参数传递给元类:
class foo(object, metaclass=something, kwarg1=value1, kwarg2=value2): ...4.为什么需要元类元类最主要的一个应用方向是创建api,一个最著名的应用是django orm,比如:
class person(models.model): name = models.charfield(max_length=30) age = models.integerfield()当你这样访问属性的时候:
person = person(name='bob', age='35')print(person.age)它并不会返回models.integerfield,而是返回了一个整形的数字。
这是因为models.model引用了一个modelbase类,该类随后进行了魔术般地操作,使其能够与数据库字段进行挂钩。
这就是元类的作用,django通过它,完成了系列复杂的幕后工作,将原本非常复杂的事情变得非常简单。
黑巷少年 电瓶修复技术—软化解决不难了,热修复还神奇吗?
解读漫游费的前世今生,漫游费真相大调查,
Enabot桌面机器人内部拆解分析
组合逻辑电路的分析和设计
IDC通过BGP主备链路上云方案
Python中元类的作用
恒温荧光检测仪与实时荧光PCR的应用领域
三大原因促使苹果放弃英特尔芯片选择自研
上半年LED室内照明市场规模同比增长36%
Maxim发布具有最高效率和最小方案尺寸的AI系统供电电源芯片组
微软承认俄罗斯黑客成功对他们进行了网络攻击
BOE(京东方)全新柔性OLED屏幕助力一加Ace Pro显示画质大幅升级
基于RFID技术的宿舍考勤设计
如何使用ModelGauge m5 EZ为电量计锂离子电池加油
差分晶振在高清视频处理器的应用
一加6T将迎来新功能:用于相机对焦
【行业资讯】 Semtech携手复旦微电子推出MCU+SX126x参考设计
可携式扬声器的制作教程
数据库select语句的基本用法
《人民日报》关注中国量子算力在移动通信领域的应用