Python中構造方法和初始化方法

2021-09-02 19:58:26 字數 4538 閱讀 4012

在python中建立乙個新式類時,一般都會定義乙個__init__方法,用來對類的例項進行初始化。但是__init__方法並不是類的構造方法,類中真正的構造方法是__new__方法。

看看下面的例子:

class

test

:def

__init__

(self)

:print

('__init__ method in {}'

.format

(self.__class__)

)def

__new__

(cls,

*args,

**kwargs)

:print

('__new__ method in {}'

.format

(cls)

)return

super

(test, cls)

.__new__(cls,

*args,

**kwargs)

test = test(

)# 輸出為:

# __new__ method in

# __init__ method in

從上例可以看出,當例項化類時,類的__new__方法先被呼叫,然後是__init__方法。

一般來說, 類的__new__方法和__init__方法都會是下面的形式:

def

__new__

(cls,

*args,

**kwargs)

:# do something

obj =..

.return obj

def__init__

(self,

*args,

**kwargs)

:# do something

對於類的__new__方法和__init__方法可以概括為:

__new__方法是新式類中的方法,它具有以下特性:

如果(新式)類中沒有重寫__new__方法,預設是呼叫該類的直接父類的__new__方法來建立類的例項。如果該類的父類也沒有重寫__new__方法,那麼將一直按照繼承鏈向上追溯至object類的__new__方法。

如果(新式)類中重寫了__new__方法,那麼可以選擇任意乙個其他新式類(必須是新式類,只有新式類有__new__方法,因為object類是所有新式類的基類)的__new__方法來建立例項,其中包括這個新式類的父類和子孫類,只要它們不會造成遞迴死迴圈。

看看下面的例子:

class

animal

:def

__new__

(cls,

*args,

**kwargs)

: obj =

super

(animal, cls)

.__new__(cls,

*args,

**kwargs)

""" 這裡的super(animal, cls).__new__(cls, *args, **kwargs) 也可以寫成如下形式:

1. object.__new__(cls, *args, **kwargs)

2. object.__new__(animal, *args, **kwargs)

3. cat.__new__(cls, *args, **kwargs)

4. people.__new__(cls, *args, **kwargs) 即使people類和animal類沒有關係,也是可以呼叫的;

在任何新式類中,不能呼叫自身的 『__new__』 方法來建立例項,因為這樣會造成死迴圈。

所以要避免如下形式的呼叫:

return animal.__new__(cls, *args, **kwargs)

return cls.__new__(cls, *args, **kwargs)

"""print

('call __new__ method for {}'

.format

(obj.__class__)

)return obj

class

cat(animal)

:def

__new__

(cls,

*args,

**kwargs)

: obj =

object

.__new__(cls)

print

('call __new__ method for {}'

.format

(obj.__class__)

)return obj

class

people

:# 該類沒有 '__new__' 方法,那麼會自動呼叫其父類,即object類的 '__new__' 方法來建立例項。

pass

class

girl

:def

__new__

(cls,

*args,

**kwargs)

: obj =

object

.__new__(cat)

print

('call __new__ method for {}'

.format

(obj.__class__)

)return obj

dog = animal(

)cat = cat(

)tina = girl(

)# 輸出為:

# call __new__ method for

# call __new__ method for

# call __new__ method for

類的__new__方法決定是否使用該類的__init__方法,因為類的__new__方法可以呼叫其他類的構造方法或者直接返回別的類例項作為本類的例項。

通常來說,新式類進行例項化時,__new__方法會返回當前類的例項,然後呼叫該類的__init__方法進行例項的初始化。但是,如果__new__方法返回的不是當前類的例項,那麼,當前類的__init__方法就不會被呼叫。

請看下面的例子:

classa:

def__init__

(self,

*args,

**kwargs)

:print

('call __init__ method from {}'

.format

(self.__class__)

)def

__new__

(cls,

*args,

**kwargs)

: obj =

super

(a, cls)

.__new__(cls,

*args,

**kwargs)

print

('call __new__ method for {}'

.format

(obj.__class__)

)return obj

classb:

def__init__

(self,

*args,

**kwargs)

:print

('call __init__ method from {}'

.format

(self.__class)

)def

__new__

(cls,

*args,

**kwargs)

: obj =

super

(b, cls)

.__new__(a,

*args,

**kwargs)

print

('call __new__ for {}'

.format

(obj.__class__)

)return obj

b = b(

)print

(type

(b))

# 輸出為:

# call __new__ for

#

可以看到,類b在例項化時並未呼叫自身的的初始化方法__init__。因為類b的構造方法返回的是類a的例項。

靜態初始化塊 初始化塊 構造方法

1.所有的靜態初始化塊都優先執行,其次才是非靜態的初始化塊和建構函式,它們的執行順序是 1 父類的靜態初始化塊 2 子類的靜態初始化塊 3 父類的初始化塊 4 父類的建構函式 5 子類的初始化塊 6 子類的建構函式 注意 1 此處的構造方法需要與自己的類名相同,2 靜態 初始化塊需要用 2.構造方法...

物件構造和初始化

1 構造方法 物件都有構造方法,如果沒有,則新增乙個default方法 抽象類有構造方法 2 呼叫本類和父類 this 本類其他 super父類 父類所有構造方法都得到呼叫 例 classa class bextends a 不能通過編譯 1.class a a int a 2.classa3.cl...

建構函式初始化列表和初始化函式

其實並沒有所謂的初始化函式的概念,本文中的初始化函式只是說明在函式體內進行賦值。而初始化列表才是真正意義上的物件初始化。使用初始化列表效率會高一點。c 規定,物件的成員變數的初始化動作發生在進入建構函式本體之前。在建構函式體內只是賦值,並不是初始化。請看下面這個栗子 class base publi...