Python實例化class的執行順序

Python裏對類的實例化時有怎樣的順序
通常來講一個類裏面有類變量和方法,好比咱們定義一個名爲A的類python

class A():
    bar = "my lover love me"
    
    def __init__(self, name):
        print('A的class' ,self.__class__, name)

咱們在這個類裏面定義了一個類變量bar和一個構造方法__init__,那麼咱們實例化A()時都發生了什麼呢!看官不要急,聽我慢慢道來...this

  • 首先,python 調用內置的type類,沒有聽錯,就是咱們平時用來測引用類型的那個type,而後type調用內置的元類mateClass,mateClass再調用__new__方法將類實例化,此時完成了第一步
  • 而後,這個實例將會初始化本身的類變量,就是把本身從頭至尾掃視一遍,
  • 以後,進入構造方法,並初始化本身的實例變量。

注意:python中類變量和實例變量是不同的,

類變量:不用實例化也能夠訪問。
實例變量:是動態建立的。必須實例化以後才能夠訪問,由於以前是不存在的。翻譯

好比下面這個例子:不實例化訪問類變量code

class A():
    a = 2
print(A.a)

輸出:
>>>2

說了這麼多,上代碼。看看類繼承時怎麼運行的:對象

class A():
    def __init__(self, name):
        print('A的class' ,self.__class__, name)
        
class B(A):
    def __init__(self, name):
        self._name = name
        A.__init__(self, name)
        print('B的class', self.__class__, name)
    print('this is B class')
        
class C(B):
    def __init__(self, name):
        B.__init__(self, name)
        print('C的class')
        
if __name__ == '__main__':

c = C('lee')

輸出以下:繼承

this is B class
A class <class '__main__.C'> lee
B class <class '__main__.C'> lee
C class

來現身說法,解釋一波文檔

  • 首先對class C()進行實例化,從頭至尾掃一遍,而後進入C()的構造,遇到了父類C()的構造方法B.__init__。
  • 進入class B(),從頭至尾掃一遍,執行了print('this is B class')語句而後進入B()的構造,遇到了父類B()的構造方法A.__init__。
  • 進入class A(),從頭至尾掃一遍,而後進入A()的構造方法A.__init__。而後A.__init__執行完畢並彈出棧,class A()執行完畢並彈出棧。
  • 回到class B(),從上次未執行完的地方print('B的class', self.__class__, name)繼續執行。而後B.__init__執行完畢並彈出棧,class B()執行完畢並彈出棧。
  • 回到class C(),從上次未執行完的地方print('C的class')繼續執行。而後C.__init__執行完畢並彈出棧,class C()執行完畢並彈出棧。程序運行完畢。
  • 因爲是對class C()進行實例化,上面的self都是指class C()的實例而不是class A()的或者class B()的。所以self.__class__清一色的顯示<class '__main__.C'>而不是<class '__main__.A'>或<class '__main__.B'>。

隨便補充一下使用type關鍵字動態建立類的知識點,敲黑板、、、我要用CET3.5的英語水平向你們翻譯一部分官方文檔對type的描述啦。字符串

使用三個參數,返回一個新類型對象。這其實是類語句的動態形式。名稱字符串是類名,併成爲 __name__屬性;基元元組列出基類併成爲> __bases__屬性;而且dict字典是包含類主體定義的命名空間,並被複制到標準字典以成爲 __dict__屬性。

怎麼樣,是否是很拗口,是否是大寫的懵*。so,上代碼,如下兩種寫法輸出同樣的都是輸出:重寫name方法 1it

class X():
    a = 1
    def __name__(self):
    return '重寫name方法'   
x =X()
print(x.__name__(), x.a)

X = type('重寫name方法', (object,), dict(a = 1))
x = X()
print(X.__name__, x.a)

type動態建立實例化時,第一個參數就至關於重寫了類的__name__方法。X類但__name__屬性卻不叫X,呵,好反人類的寫法
還好咱們通常不是這麼變態,一般咱們會將這兩個定義成相同的名字,以下:都叫X
X = type('X', (object,), dict(a = 1))
歡迎你們踊躍評論,提出建議哦~class

先更新到這裏。。。。 2018/10/09

相關文章
相關標籤/搜索