本文始发于我的公众号:TechFlow,原创不易,求个关注程序员
今天是Python专题的第16篇文章,今天咱们来聊聊Python当中的元类。web
元类是Python当中的高级用法,若是你以前历来没见过这个术语或者是没据说过这个概念,这是很是正常的,由于一方面它的使用频率不高,另一方面就是它相对不太容易理解。以致于不少Python开发者都理解得不是很深刻,致使了市面上相关的资料也并不太多。我也是读了一些大牛的代码才开启了这扇新世界的大门。编程
咱们以前的时候曾经介绍过,在Python当中一切都是对象,注意,是一切都是对象。咱们都知道对象是类实例化以后的结果,能够简单地将类和对象类比成模具和成品的关系。模具是类,而根据模具作出来的产品是对象。数组
这个比喻思想比较接近,可是不完美。由于实际当中一个模具能够作出多个产品,一个产品只有一个模具。但编程语言当中不一样,因为类之间能够继承以及多继承,也就是说一个对象能够对应多个类。因此这个比喻不是特别合适,可是类和对象的关系是没错的。编程语言
可是这就有了一个问题,既然Python当中一切都是对象,那么是否是说类其实也是一个对象呢?也就是说一个模具其实也是另一个模具的产品?一样,这个模具的模具其实也是另一个模具的产品,那么咱们一直追问下去会怎么样呢?编辑器
很简单,咱们作个实验就知道了,咱们能够用_class__关键字来查看一个变量的类型,那么咱们反复调用就能够查看其中的关系了:函数
从上面的图中咱们能够发现,num是int类型的变量。咱们继续查看int这个类型的类型,获得了type类型。而当咱们去查看type的类型的时候,会发现咱们获得的仍是一个type的类型。spa
因此咱们能够明白了,type是Python中用来建立全部类的元类,是全部模具的模具。在Python当中,咱们把一个类的类叫作元类(metaclass)。因此type就是Python当中内置的元类,咱们也能够本身建立咱们须要的元类。经过元类,咱们建立的对象也是一个类,而不是一个实例。code
理解了type是一切类基础以后,再来看动态类就简单了。动态类是动态语言最大的特性之一,做为典型的动态语言,Python天然也是支持类型的动态建立的。cdn
在Python当中,建立动态类型的一种方式就是经过type关键字。提及来有些意想不到,type函数不是用来查询对象所属的类型的吗,怎么还能够建立类呢?
这实际上是type的另一种用法,做为元类来建立一个类。在这种用法,type函数接收3个参数,分别是类型的名称,父类的元组,以及一个字典。除了第一个参数以外,后面两个参数均可觉得空。好比咱们来看一个例子:
注意,type返回的结果是一个类,而不是一个实例。因此咱们还能够经过它建立实例:
hello = Hello()
复制代码
这样建立出来的是最简单的空类,它什么也没有,和下面的代码等价。
class Hello:
pass 复制代码
咱们也能够在type的参数当中为这个类填充属性和方法:
def hello_world(self):
print('hello') Hello = type('Hello', (), {'hello':hello_world, 'num': 3}) 复制代码
这样咱们就为Hello这个类建立了一个方法叫作hello,一个属性num等于3。咱们能够来调用一下试试:
也就是说咱们可使用type来根据咱们的须要自行定义类,只不过type既能够获取对象的类型又能够建立新的类,看起来可能以为有些不太直观,可是其实这也是说得通的。咱们在Python当中经过调用str建立一个string对象,经过int来建立一个integer对象,那么经过type则是建立一个类的对象。
咱们以前说了,当咱们使用type来建立类的时候,还能够传入父类的元组从而实现类的继承。
好比咱们再建立一个叫作World的类继承刚才经过type建立出来的Hello类,而后在为它加上额外的函数:
def say_world(self):
print('World') World = type('World', (Hello, ), {'world': say_world}) 复制代码
注意这里传入第二个参数是父类的元组,既然是元组,那么当元素只有一个的时候,须要加上逗号,表示这是一个元组。这样建立出来的类和咱们经过class定义的静态类效果是同样的:
也就是说,咱们能够先把函数实现,而后再根据任务的须要把这些函数组装成新的类。显然,这和传统的C++以及Java这些静态类型的语言相比,要灵活得多。
咱们当然能够经过type来建立动态建立类,可是从上面的使用过程也应该看得出来,这样使用起来并不太方便,而且不少进阶的功能很难实现。举个简单的例子,好比咱们想要动态地为一个已有的类添加一些动态的方法,生成新的类。咱们使用type就很难实现。type也的确不是Python元类的主要运用,metaclass才是王道,但因为篇幅限制,这部分将放在下一篇文章当中。
固然,元类是一个很是高级的用法,以致于Python的创始人说99%的Python程序员并不须要用到它。因此若是你以为理解起来很是费劲的话也没有关系,知道这么个概念就能够了。
今天的内容就是这些,若是喜欢本文,能够的话,请点个关注,给我一点鼓励,也方便获取更多文章。