Table of Contents
在python中,一切皆是对象,我们通过类可以创建出来对象,但是类本身也是对象,我们可以通过type方法查看一个对象是被哪个类所创建的,如下
>>> class Student(object):
pass
>>> student = Student() #创建一个对象
>>> type(student)
<class '__main__.Student'> #该对象是被Student类所创建的
那么,Student类 也是一个对象,那么它是通过谁创建的呢?
我们通过type函数再来查看一下Student是被创建的
>>> type(Student)
<class 'type'>
我们可以看到 Studnet 类 这个 对象,是被type创建的。
type
其实type不光可以查看一个对象是通过谁创建的,它还可以创建一个类对象
如下所示:
>>> def hello(self):
print('hello')
>>> Student = type('Studnet',(object,),{'hello':hello,'name':'zzh'}) #type返回的是类对象,注意不是类
>>> type(Student) #我们可以看到这个类对象是由 type创建出来的,也就是说这是一个type类的对象
<class 'type'>
>>> s = Student() #我们再通过 Student这个类对象中的 构造方法,创建出来一个对象
>>> type(s)
<class '__main__.Studnet'>
>>> s.hello() #调用方法
hello
>>> s.name #调用属性
'zzh'
注意:我们平时是通过类名加小括号来创建对象的,其实是通过 类对象名 加小括号来创建对象,python会自动的将我们的类对象名 与 类名保持一致。
但当我们通过type去动态的创建一个类的时候,我们可以将类名与类对象名设置为不同。
如下
>>> Student1111 = type('Student',(object,),{'hello':hello,'name':'zzh'}) #类名为Studnet,类对象名为#Student111
>>> a = Student() # 通过类名加小括号创建对象报错
Traceback (most recent call last):
File "<pyshell#74>", line 1, in <module>
a = Student()
NameError: name 'Student' is not defined
type函数接收3个参数
1: 要被创建的类名 --str
2: 被创建的类的父类 --tuple
3: 该类中的方法和属性 -- dict
当我们定义一个类并运行代码的时候,python就会通过type方法去为我们创建这个类对象。
元类 -- metaclass
其实我们创建对象实际上是通过类中的__new__方法,元类的作用就是通过重写 __new__ 方法从而 控制对象的创建,我们可以更改 对象的属性名,或者给一个对象动态添加一些函数
如下:
先解释一下:
由于类对象最终是通过type函数来创建,type又是通过其内部的__new__函数进行创建
当我们自定义一个元类的时候,实际上是在type创建类对象向之前,先进行拦截,更改里面的一些属性或方法,然后再将更改后的信息传递给type的__new__函数。
__new__ 函数一共需要4个参数:
参数1:类似于self,传的是要被创建类对象的那个类本身。
参数2:类名
参数3:继承的类
参数4:类中的属性以及函数,会以dict的形式传