Python进阶之新式类与经典类
1、什么是新式类,什么是经典类
# -*- coding: utf-8 -*-
class A:
pass
class B(object):
pass
A是经典类,B是新式类,这是Python2.x 里所特有的现象,之所以要提到经典类和新式类,是要把一些基础的东西讲清楚。
2、那个特殊的self
# -*- coding: utf-8 -*-
class A:
def __init__(self):
self.name = 'lili'
def printA(self):
print self.name
a = A()
a.printA()
代码执行后输出字符串“lili”
上面这段代码隐藏几个重要的知识点
- A() 返回一个对象,a 是一个变量,它指向了这个刚刚创建出来的对象
__init__(self)
是一个特殊的函数,它在A() 执行的过程中被执行- a.printA(),执行了printA 这个函数,注意,函数 printA 是有一个参数的,名字叫self,那么当这个函数被执行时,self传入的实参是什么?答案是a
关于前两条,你大概能理解,可能对于第三条,就有些疑惑了,有过其他语言基础的朋友,理解起来会容易一些,这个self其实相当于this。
再换一段代码来理解:
# -*- coding: utf-8 -*-
class A:
def __init__(self):
self.name = 'lili'
def printA(self):
print id(self)
print self.name
a = A()
print id(a)
a.printA()
函数id()可以获得一个变量在内存里的地址,上面的代码执行结果是
4404072032
4404072032
lili
变量a的内存地址和函数printA中的self内存地址是一样的,这就说明,它们是同一个东西,由此,就牵扯出另一个话题,__init__
的作用是什么
3、__init__
当A()执行时,必然要有一个创建对象的过程,那么__init__
是用来创建对象的么?不是,因为__init__
函数里有一个self参数,上面已经解释过了,self其实就是对象。
__init__
的作用是初始化对象,对象刚刚被创建出来以后,我们要对它进行初始化的工作,示例中的初始化很简单,只初始化了一个属性,self.name = 'lili'
,初始化对象,是为了在创建完对象以后,就希望它具有一些属性,或是做一些操作,比如读取配置文件,都可以在__init__
中进行。
那么对象是在什么时候被创建的呢?坦率的讲,对于经典类,我也说不清楚对象是在哪里创建出来的,但肯定不是__init__
创建出来的,综合一些帖子里的说法,经典类有一个隐含的超类object,那么想必是这个隐含的超类完成了对象的创建动作。
4、__new__
关于对象如何创建,新式类的出现,可以做一些更明确的解答
# -*- coding: utf-8 -*-
class Stu(object):
def __init__(self,name):
self.name = name
print '__init__后执行'
def __new__(cls, *args, **kwargs):
print cls
print u'__new__创建对象,因此先执行'
obj = object.__new__(cls,*args, **kwargs)
print id(obj)
return obj
stu = Stu(u'小刚')
print id(stu)
显式的继承object,就是新式类,而在新式类里,有一个特殊方法 __new__
,它的作用就是创建出对象。
因为是要创建对象,因此会在__init__
前面执行,__new__
方法里有一个参数cls,这个是什么呢?执行上面的代码,得到如下结果
<class '__main__.Stu'>
__new__创建对象,因此先执行
4542614864
__init__后执行
4542614864
cls 正是类Stu ,在Stu的__new__
方法里,超类object调用了它自己的__new__
方法,传入的是Stu类,返回的是Stu类的对象,关于这一点,id函数返回的内存地址可以作证。