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”

上面这段代码隐藏几个重要的知识点

  1. A() 返回一个对象,a 是一个变量,它指向了这个刚刚创建出来的对象
  2. __init__(self) 是一个特殊的函数,它在A() 执行的过程中被执行
  3. 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函数返回的内存地址可以作证。

原文链接:
http://www.zhangdongshengtech.com/article-detials/87

上一篇:Python面向对象编程之封装、继承与多态

下一篇:做python Web开发你要理解:WSGI & uWSGI & Nginx & Flask