说说Python中的__new__和__init__的区别?(上)

简介: 公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助!

小猿会从最基础的面试题开始,每天一题。如果参考答案不够好,或者有错误的话,麻烦大家可以在留言区给出自己的意见和讨论,大家是要一起学习的 。


废话不多说,开始今天的题目:


问:说说Python中的__new__和__init__的区别?

答:在Python中__new__和__init__具有不同的功能。并且对于Python的新类和旧类而言功能也不同。


__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是个静态方法。


__init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值,通常用在初始化一个类实例的时候。是一个实例方法。


主要区别在于:__new__是用来创造一个类的实例的,而__init__是用来初始化一个实例的。


下文来源于:

https://www.jianshu.com/p/14b8ebf93b73


Python的新类和旧类

Python中的类分为新类和旧类。旧类是Python3之前的类,旧类并不是默认继承object类,而是继承type类。

Python2中的旧类如下面代码所示:

class oldStyleClass: # inherits from 'type'
    pass

Python2中定义一个新类:

class newStyleClass(object): # explicitly inherits from 'object'
    pass

在Python3中所有的类均默认继承object,所以并不需要显式地指定object为基类。

object为基类可以使得所定义的类具有新类所对应的方法(methods)和属性(properties)。

在下面的文章中我们会分别基于新类和旧类探讨__new____init__

__new____init__参数的不同

__new__所接收的第一个参数是cls,而__init__所接收的第一个参数是self。这是因为当我们调用__new__的时候,该类的实例还并不存在(也就是self所引用的对象还不存在),所以需要接收一个类作为参数,从而产生一个实例。而当我们调用__init__的时候,实例已经存在,因此__init__接受self作为第一个参数并对该实例进行必要的初始化操作。这也意味着__init__是在__new__之后被调用的。

Python旧类中的__new____init__

Python的旧类中实际上并没有__new__方法。因为旧类中的__init__实际上起构造器的作用。所以如果我们定义如下旧类:

class oldStyleClass:
    def __new__(cls):
        print("__new__ is called") # this line will never get called during construction
oldStyleClass()

程序输出结果如下:

<__main__.oldStyleClass instance at 0x109c45518>

可见创建及初始化对象的过程并没有调用__new__。实际上,除非显式调用:oldStyleClass.__new__(oldStyleClass),该类中的__new__方法中的内容永远不会被调用。因为旧类构造实例并不会调用__new__方法。

但如果我们重载__init__方法:

class oldStyleClass:
    def __init__(self):
        print("__init__ is called")
oldStyleClass()

该程序将会输出

__init__ is called
<__main__.oldStyleClass instance at 0x1091992d8>

如果我们在__init__中加上return语句,将会导致TypeError: __init__() should return None的错误。

class oldStyleClass:
    def __init__(self):
        return 29
oldStyleClass()

程序结果如下:

TypeError: __init__() should return None

这意味着对于Python的旧类而言,我们无法控制__init__函数的返回值。

相关文章
|
2天前
|
算法 Java C++
C++和Python在内存管理上的主要区别是什么?
【7月更文挑战第2天】C++和Python在内存管理上的主要区别是什么?
6 1
|
8天前
|
存储 Python
Python中list, tuple, dict,set的区别和使用场景
Python中list, tuple, dict,set的区别和使用场景
|
9天前
|
索引 Python
Python中append,insert和extend的区别
Python中append,insert和extend的区别
|
7天前
|
Shell Python
Python教程:return和yield的区别
Python教程:return和yield的区别
6 0
Python教程:return和yield的区别
|
20天前
|
Java Python
Python2.x 与 3​​.x 版本区别
Python2.x 与 3​​.x 版本区别
|
1天前
|
缓存 测试技术 Python
python的装饰器是什么?有什么作用?迭代器和生成器的区别?
python的装饰器是什么?有什么作用?迭代器和生成器的区别?
|
2天前
|
算法 Java C++
C++和Python在内存分配策略上的主要区别是什么?
【7月更文挑战第2天】C++和Python在内存分配策略上的主要区别是什么?
4 0
|
2天前
|
机器学习/深度学习 Java 程序员
Python和C++的区别?
【7月更文挑战第2天】Python和C++的区别?
5 0
Python中strip()、lstrip()和rstrip()方法的区别与用法详解
在Python中,字符串是一种常见的数据类型,而处理字符串时,经常会用到 strip()、lstrip() 和 rstrip() 这几个方法。它们都用于删除字符串开头和/或结尾的指定字符或字符集合,但在具体使用时有一些区别。
|
2月前
|
程序员 开发者 Python
Python2.x与 3.x 版本区别
Python2.x与 3.x 版本区别

相关实验场景

更多