公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助! 小猿会从最基础的面试题开始,每天一题。如果参考答案不够好,或者有错误的话,麻烦大家可以在留言区给出自己的意见和讨论,大家是要一起学习的 。 废话不多说,开始今天的题目: 问:说说Python中的__new__和__init__的区别? 答:在Python中__new__和__init__具有不同的功能。并且对于Python的新类和旧类而言功能也不同。 __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是个静态方法。 __init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值,通常用在初始化一个类实例的时候。是一个实例方法。 主要区别在于:__new__是用来创造一个类的实例的,而__init__是用来初始化一个实例的。 下文来源于: https://www.jianshu.com/p/14b8ebf93b73 Python中的类分为新类和旧类。旧类是Python3之前的类,旧类并不是默认继承 Python2中的旧类如下面代码所示: Python2中定义一个新类: 在Python3中所有的类均默认继承 以 在下面的文章中我们会分别基于新类和旧类探讨 Python的旧类中实际上并没有 程序输出结果如下: 可见创建及初始化对象的过程并没有调用 但如果我们重载 该程序将会输出 如果我们在 程序结果如下: 这意味着对于Python的旧类而言,我们无法控制 Python的新类允许用户重载 如下面代码是所示: 结果如下: 创建类实例并初始化的过程中 这里需要注意的是,如果 执行结果如下: 同时另一个需要注意的点是: 如果我们在 如下面代码所示: 执行结果如下: 可见如果 只有在 输出结果为: 如果对于参考答案有不认同的,大家可以在评论区指出和补充,欢迎留言! 更多题目: 关注小猿公众号,每天学习一道题Python的新类和旧类
object
类,而是继承type
类。class oldStyleClass: # inherits from 'type'
passclass newStyleClass(object): # explicitly inherits from 'object'
passobject
,所以并不需要显式地指定object
为基类。object
为基类可以使得所定义的类具有新类所对应的方法(methods
)和属性(properties
)。__new__
和__init__
。__new__
和__init__
参数的不同__new__
所接收的第一个参数是cls
,而__init__
所接收的第一个参数是self
。这是因为当我们调用__new__
的时候,该类的实例还并不存在(也就是self
所引用的对象还不存在),所以需要接收一个类作为参数,从而产生一个实例。而当我们调用__init__
的时候,实例已经存在,因此__init__
接受self
作为第一个参数并对该实例进行必要的初始化操作。这也意味着__init__
是在__new__
之后被调用的。Python旧类中的
__new__
和__init__
__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
__init__
函数的返回值。Python新类中的
__new__
和__init__
__new__
和__init__
方法,且这两个方法具有不同的作用。__new__
作为构造器,起创建一个类实例的作用。而__init__
作为初始化器,起初始化一个已被创建的实例的作用。class newStyleClass(object):
# In Python2, we need to specify the object as the base.
# In Python3 it's default.
def __new__(cls):
print("__new__ is called")
return super(newStyleClass, cls).__new__(cls)
def __init__(self):
print("__init__ is called")
print("self is: ", self)
newStyleClass()__new__ is called
__init__ is called
self is: <__main__.newStyleClass at 0x109290890>
<__main__.newStyleClass at 0x109290890>__new__
和__init__
被调用的顺序也能从上面代码的输出结果中看出:__new__
函数首先被调用,构造了一个newStyleClass
的实例,接着__init__
函数在__new__
函数返回一个实例的时候被调用,并且这个实例作为self
参数被传入了__init__
函数。__new__
函数返回一个已经存在的实例(不论是哪个类的),__init__
不会被调用。如下面代码所示:obj = 12
# obj can be an object from any class, even object.__new__(object)
class returnExistedObj(object):
def __new__(cls):
print("__new__ is called")
return obj
def __init(self):
print("__init__ is called")
returnExistedObj()__new__ is called
12__new__
函数中不返回任何对象,则__init__
函数也不会被调用。class notReturnObj(object):
def __new__(cls):
print("__new__ is called")
def __init__(self):
print("__init__ is called")
print(notReturnObj())__new__ is called
None__new__
函数不返回对象的话,不会有任何对象被创建,__init__
函数也不会被调用来初始化对象。总结几个点
__init__
不能有返回值__new__
函数直接上可以返回别的类的实例。如上面例子中的returnExistedObj
类的__new__
函数返回了一个int
值。__new__
返回一个新创建属于该类的实例时当前类的__init__
才会被调用。如下面例子所示:class sample(object):
def __str__(self):
print("sample")
class example(object):
def __new__(cls):
print("__new__ is called")
return sample()
def __init__(self):
print("__init__ is called")
example()__new__ is called
sample
联系客服