本节内容
1、概述
2、类的起源
3、__new__方法
4、__metaclass__方法
一、概述
前面我们学习了大篇幅的关于类,通过类创建对象,那我们想知道这个类到底是怎么产生的呢?它的一切来源是什么?还有对象,对象是通过什么方法创建的,现在我们一头雾水,行的,下面我们就来揭开类的面纱,看看类和对象到底是怎么创建的,通过什么创建的。
二、类的起源
2.1 传统创建类
1
2
3
4
5
|
class
Foo(
object
):
def
__init__(
self
,name):
self
.name
=
name
f
=
Foo(
"shuaigaogao"
)
|
f 是通过 Foo 类实例化的对象,其实,不仅 f 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象,按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。
1
2
|
print
(
type
(f))
#输出:<class '__main__.Foo'> 表示:f 对象由Foo类创建
print
(
type
(Foo))
#输出:<class 'type'> 表示:Foo类对象由 type 类创建
|
所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建
2.2 type创建类
说明: type创建类的格式,类名 = type('类名',(父类,),{'方法名':方法的内存地址})
1
2
3
4
5
6
7
8
9
10
11
12
13
|
def
func(
self
):
#创建方法
print
(
"hello {0}"
.
format
(
self
.name))
def
__init__(
self
,name):
#创建构造方法
self
.name
=
name
#通过type创建类,如果是经典类的话则写成:Foo = type("Foo",(),{"talk":func,"__init__":__init__})
Foo
=
type
(
"Foo"
,(
object
,),{
"talk"
:func,
"__init__"
:__init__})
f
=
Foo(
"shuaigaogao"
)
#创建对象
f.talk()
#输出
hello shuaigaogao
|
总结:类 是由 type 类 实例化产生的
值得注意的是,新式类的写法,在继承父类那边,你继承一个父类后面就要加一个逗号,加逗号,它就把它当做一个元组,不加逗号,就是一个值了
三、__new__方法
3.1 概念
new方法是类自带的一个方法,可以重构,__new__方法在实例化的时候也会执行,并且先于__init__方法之前执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
Foo(
object
):
def
__init__(
self
,name):
self
.name
=
name
print
(
"Foo __init__"
)
def
__new__(
cls
,
*
args,
*
*
kwargs):
print
(
"Foo __new__"
,
cls
,
*
args,
*
*
kwargs)
return
object
.__new__(
cls
)
f
=
Foo(
"shuaigaogao"
)
#输出
Foo __new__ <
class
'__main__.Foo'
> shuaigaogao
#执行了new方法
Foo __init__
#执行了__init__方法
|
3.2 new方法作用
作用:所有对象都是通过new方法来实例化的,new里面调用了init方法,所以在实例化的过程中先执行的是new方法,而不是init方法。
①重构__new__方法
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class
Foo(
object
):
def
__init__(
self
,name):
self
.name
=
name
print
(
"Foo __init__"
)
def
__new__(
cls
,
*
args,
*
*
kwargs):
print
(
"Foo __new__"
,
cls
,
*
args,
*
*
kwargs)
f
=
Foo(
"shuaigaogao"
)
#实例化
#输出
Foo __new__ <
class
'__main__.Foo'
> shuaigaogao
|
由上面的例子看出,没有执行__init__方法
②重构__new__方法,并继承父类的__new__方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
Foo(
object
):
def
__init__(
self
,name):
self
.name
=
name
print
(
"Foo __init__"
)
def
__new__(
cls
,
*
args,
*
*
kwargs):
#cls相当于传入类Foo
print
(
"Foo __new__"
,
cls
,
*
args,
*
*
kwargs)
return
object
.__new__(
cls
)
#继承父类的__new__方法,这边必须以返回值的形式继承
f
=
Foo(
"shuaigaogao"
)
#输出
Foo __new__ <
class
'__main__.Foo'
> shuaigaogao
Foo __init__
|
由上面不难看出,大多数情况下,你都不要去重构你的__new__方法,因为你父类中已经有__new__方法了,已经帮你写好了怎么去创建类,如果你重写的话,就会覆盖父类的里面的__new__方法。但是你重构可以增加一点小功能,但是你覆盖了以后还是需要继承父类回来,要不然你的这个实力就创建不了。
3.3 使用场景
我想对我自己写的一些类进行定制,就在它实例化之前就进行定制,就可以用到__new__方法,new方法就是用来创建实力的,重构new方法,必须以返回值的形式继承父类的new方法。
①需求:我在创建对象时候,同时创建一个类变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class
Foo(
object
):
def
__init__(
self
,name):
self
.name
=
name
print
(
"Foo __init__"
)
def
__new__(
cls
,
*
args,
*
*
kwargs):
#cls相当于是传入的类名Foo
cls
.name
=
"shuaigaogao"
#创建对象是定义静态变量
print
(
cls
.name)
return
object
.__new__(
cls
)
#继承父类的__new__方法
f
=
Foo(
"shuaigaogao"
)
print
(Foo.name)
#输出
shuaigaogao
Foo __init__
shuaigaogao
|
四、__metaclass__方法
4.1 metaclass作用
metaclass这个属性叫做元类,它是用来表示这个类是由谁来帮他实例化创建的,说白了,就是相当于自己定制一个类,就这么一个意思。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
class
MyType(
type
):
def
__init__(
self
,
*
args,
*
*
kwargs):
print
(
"Mytype __init__"
,
*
args,
*
*
kwargs)
def
__call__(
self
,
*
args,
*
*
kwargs):
print
(
"Mytype __call__"
,
*
args,
*
*
kwargs)
obj
=
self
.__new__(
self
)
print
(
"obj "
,obj,
*
args,
*
*
kwargs)
print
(
self
)
self
.__init__(obj,
*
args,
*
*
kwargs)
return
obj
def
__new__(
cls
,
*
args,
*
*
kwargs):
print
(
"Mytype __new__"
,
*
args,
*
*
kwargs)
return
type
.__new__(
cls
,
*
args,
*
*
kwargs)
class
Foo(
object
,metaclass
=
MyType):
#python3统一用这种
#__metaclass__ = MyType #python2.7中的写法
def
__init__(
self
,name):
self
.name
=
name
print
(
"Foo __init__"
)
def
__new__(
cls
,
*
args,
*
*
kwargs):
print
(
"Foo __new__"
,
cls
,
*
args,
*
*
kwargs)
return
object
.__new__(
cls
)
f
=
Foo(
"shuaigaogao"
)
print
(
"f"
,f)
print
(
"fname"
,f.name)
#输出
Mytype __new__ Foo (<
class
'object'
>,) {
'__new__'
: <function Foo.__new__ at
0x0000025EF0EFD6A8
>,
'__init__'
: <function Foo.__init__ at
0x0000025EF0EFD620
>,
'__qualname__'
:
'Foo'
,
'__module__'
:
'__main__'
}
Mytype __init__ Foo (<
class
'object'
>,) {
'__new__'
: <function Foo.__new__ at
0x0000025EF0EFD6A8
>,
'__init__'
: <function Foo.__init__ at
0x0000025EF0EFD620
>,
'__qualname__'
:
'Foo'
,
'__module__'
:
'__main__'
}
Mytype __call__ shuaigaogao
Foo __new__ <
class
'__main__.Foo'
>
obj <__main__.Foo
object
at
0x0000025EF0F05048
> shuaigaogao
<
class
'__main__.Foo'
>
Foo __init__
f <__main__.Foo
object
at
0x0000025EF0F05048
>
fname shuaigaogao
|
创建过程如下:
4.2 执行顺序
类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__
metaclass 详解文章:猛击这里 得票最高那个答案写的非常好