1. 程式人生 > >Python中的__new__方法

Python中的__new__方法

只有繼承於object的新式類才能有__new__方法,__new__方法在建立類例項物件時由Python直譯器自動呼叫,一般不用自己定義,Python預設呼叫該類的直接父類的__new__方法來構造該類的例項,如果該類的父類也沒有重寫__new__,那麼將一直按此規矩追溯至object的__new__方法,因為object是所有新式類的基類,若需要自定義__new__方法,一般用法如下:

class Person(object):
    def __new__(cls):
        return  object.__new__(cls)

__new__至少要有一個引數cls,代表要例項化的類,此引數在例項化時由Python直譯器自動提供;__new__必須要有返回值,返回例項化出來的例項,可以return父類new出來的例項,或直接是object的new出來的例項。


object.new(cls)執行完返回的結果為Person類的例項物件,如下:

class Person(object):
    def __init__(self):
        print("__init__")
        self.name="張三"
    def __new__(cls):
        print('__new__')
        ob = object.__new__(cls)#ob為Person例項物件
        print(ob)
        return ob
p1 = Person()
print(p1.name)

在這裡插入圖片描述


p1=Person()該語句主要做了以下工作:
首先呼叫Person的__new__方法,該方法通過object.new(cls)建立了Person例項物件,並返回。最後呼叫了該Person例項物件的__init__方法。

object.new()方法接收的引數是類物件,可以不是當前類物件cls,如果將cls換成其他類物件會發生什麼呢,看下面程式碼的執行結果:

class Dog(object):
    def __init__(self):
        self.name="旺財"
        print("Dog.__init__")
class Person(object):
    def __init__(self):
        self.name="張三"
        print("Person.__init__")
    def __new__(cls):
        print('__new__')
        ob = object.__new__(Dog)
        return ob
p1 = Person()
print(type(p1))

在這裡插入圖片描述
由結果得知p1是Dog類的例項,但是有個問題,Python直譯器沒有自動執行__init__方法,由結果可以看出並沒有列印字串__init__。若__new__()沒有正確返回當前類cls的例項,那__init__()將不會被呼叫。 我們可以在__new__方法中手動呼叫__init__方法(實際開發中好像沒什麼用)

class Dog(object):
    def __init__(self):
        self.name="旺財"
        print("__init__")

class Person(object):
    def __init__(self):
        self.name="張三"
        print("__init__")
    def __new__(cls):
        print('__new__')
        ob = object.__new__(Dog)
        ob.__init__()
        return ob

p1 = Person()
print(type(p1))
print(p1.name)

在這裡插入圖片描述