首先,只有新式類纔有魔法方法__new__(),從Object類繼承的子類,都是新式類。
object類關於__new__()的定義如下:
@staticmethod # known case of __new__
def __new__(cls, *more): # known special case of object.__new__
""" T.__new__(S, ...) -> a new object with type S, a subtype of T """
pass
參數說明:
(1)object將__new__()定義成靜態方法。
(2)傳入的參數至少一個cls參數,cls表示需要實例化的類。
如何使用,舉個例子:
class A(object):
def __init__(self, value):
print "into __init__"
self.value = value
def __new__(cls, *args, **kwargs):
print "into __new__"
return super(A, cls).__new__(cls, *args, **kwargs)
a = A(10)
# 結果如下:
# into __new__
# into __init__
可發現,在調用__init__()初始化前,先調用了__new__()。
在新式類中,__new__()對當前類進行了實例化,並將實例返回,傳給了__init__(),__init__()方法中是self就是__new__()傳過來的。
但是,執行了__new__(),並不一定會進入__init__(),只有__new__()返回了,當前類cls的實例,當前類的__init__()纔會進入。
看兩個例子:
class A(object):
def __init__(self, value):
print "into A __init__"
self.value = value
def __new__(cls, *args, **kwargs):
print "into A __new__"
return object.__new__(cls, *args, **kwargs)
class B(A):
def __init__(self, value):
print "into B __init__"
self.value = value
def __new__(cls, *args, **kwargs):
print "into B __new__"
return super(B, cls).__new__(cls, *args, **kwargs)
b = B(10)
b = B(10)
# 結果:
# into B __new__
# into A __new__
# into B __init__
class A(object):
def __init__(self, value):
print "into A __init__"
self.value = value
def __new__(cls, *args, **kwargs):
print "into A __new__"
return object.__new__(cls, *args, **kwargs)
class B(A):
def __init__(self, value):
print "into B __init__"
self.value = value
def __new__(cls, *args, **kwargs):
print "into B __new__"
return super(B, cls).__new__(A, *args, **kwargs) #改動了cls變爲A
b = B(10)
# 結果:
into B __new__
into A __new__
若__new__沒有正確返回當前類cls的實例,那__init__是不會被調用的,即使是父類的實例也不行,將沒有__init__被調用。
__new__的作用
(1)
__new__方法主要是當你繼承一些不可變的class時(比如int, str, tuple), 提供給你一個自定義這些類的實例化過程的途徑。
假如我們需要一個永遠都是正數的整數類型。
class PositiveInteger(int):
def __init__(self, value):
super(PositiveInteger, self).__init__(self, abs(value))
i = PositiveInteger(-3)
print i
# -3
class PositiveInteger(int):
def __new__(cls, value):
return super(PositiveInteger, cls).__new__(cls, abs(value))
i = PositiveInteger(-3)
print i
# 3
通過重載__new__方法,我們實現了需要的功能。
(2)實現單例
一些說明:
(1)在定義子類時沒有重新定義__new__()時,Python默認是調用該類的直接父類的__new__()方法來構造該類的實例,如果該類的父類也沒有重寫__new__(),那麼將一直按此規矩追溯至object的__new__()方法,因爲object是所有新式類的基類。
(2)除了一項兩個作用外,一般__new__()使用較少,能通過__init__()實現的儘量用__init__()實現。
————————————————
版權聲明:本文爲CSDN博主「yusuiyu」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yusuiyu/article/details/87867186