python8之類的起源與metaclass

2022-05-27 03:42:16 字數 4234 閱讀 3385

前面我們學習了大篇幅的關於類,通過類建立物件,那我們想知道這個類到底是怎麼產生的呢?它的一切**是什麼?還有物件,物件是通過什麼方法建立的,現在我們一頭霧水,行的,下面我們就來揭開類的面紗,看看類和物件到底是怎麼建立的,通過什麼建立的。

class foo(object):

def __init__(self,name):

self.name = name

f = foo("shuaigaogao")

f 是通過 foo 類例項化的物件,其實,不僅 f 是乙個物件,foo類本身也是乙個物件,因為在python中一切事物都是物件,按照一切事物都是物件的理論:obj物件是通過執行foo類的構造方法建立,那麼foo類物件應該也是通過執行某個類的 構造方法 建立。

print(type(f))    #輸出:表示:f 物件由foo類建立

print(type(foo)) #輸出:表示:foo類物件由 type 類建立

所以,f物件是foo類的乙個例項foo類物件是 type 類的乙個例項,即:foo類物件 是通過type類的構造方法建立

def func(self):  #建立方法

print("hello ".format(self.name))

def __init__(self,name): #建立構造方法

self.name = name

foo = type("foo",(object,),) #通過type建立類,如果是經典類的話則寫成:foo = type("foo",(),)

f = foo("shuaigaogao") #建立物件

f.talk()

#輸出hello shuaigaogao

總結:類 是由 type 類例項化產生的

值得注意的是,新式類的寫法,在繼承父類那邊,你繼承乙個父類後面就要加乙個逗號,加逗號,它就把它當做乙個元組,不加逗號,就是乙個值了

new方法是類自帶的乙個方法,可以重構,__new__方法在例項化的時候也會執行,並且先於__init__方法之前執行.

class foo(object):

def __init__(self,name):

self.name = name

print("foo __init__")

def __new__(cls, *args, **kwargs):

print("foo __new__",cls, *args, **kwargs)

return object.__new__(cls)

f = foo("shuaigaogao")

#輸出foo __new__ shuaigaogao #執行了new方法

foo __init__ #執行了__init__方法

作用:所有物件都是通過new方法來例項化的,new裡面呼叫了init方法,所以在例項化的過程中先執行的是new方法,而不是init方法。

①重構__new__方法

class foo(object):

def __init__(self,name):

self.name = name

print("foo __init__")

def __new__(cls, *args, **kwargs):

print("foo __new__",cls, *args, **kwargs)

f = foo("shuaigaogao") #例項化

#輸出foo __new__ shuaigaogao

由上面的例子看出,沒有執行__init__方法

②重構__new__方法,並繼承父類的__new__方法

class foo(object):

def __init__(self,name):

self.name = name

print("foo __init__")

def __new__(cls, *args, **kwargs): #cls相當於傳入類foo

print("foo __new__",cls, *args, **kwargs)

return object.__new__(cls) #繼承父類的__new__方法,這邊必須以返回值的形式繼承

f = foo("shuaigaogao")

#輸出foo __new__ shuaigaogao

foo __init__

由上面不難看出,大多數情況下,你都不要去重構你的__new__方法,因為你父類中已經有__new__方法了,已經幫你寫好了怎麼去建立類,如果你重寫的話,就會覆蓋父類的裡面的__new__方法。但是你重構可以增加一點小功能,但是你覆蓋了以後還是需要繼承父類回來,要不然你的這個實力就建立不了。

我想對我自己寫的一些類進行定製,就在它例項化之前就進行定製,就可以用到__new__方法,new方法就是用來建立實力的,重構new方法,必須以返回值的形式繼承父類的new方法。

①需求:我在建立物件時候,同時建立乙個類變數

class foo(object):

def __init__(self,name):

self.name = name

print("foo __init__")

def __new__(cls, *args, **kwargs): #cls相當於是傳入的類名foo

cls.name = "shuaigaogao" #建立物件是定義靜態變數

print(cls.name)

return object.__new__(cls) #繼承父類的__new__方法

f = foo("shuaigaogao")

print(foo.name)

#輸出shuaigaogao

foo __init__

shuaigaogao

類 是由 type 類例項化產生那麼問題來了,類預設是由 type 類例項化產生,type類中如何實現的建立類?類又是如何建立物件?

答:類中有乙個屬性 __metaclass__,其用來表示該類由 誰 來例項化建立,所以,我們可以為 __metaclass__ 設定乙個type類的派生類,從而檢視 類 建立的過程。

自定義元類

類的生成 呼叫 順序依次是 __new__ --> __init__ --> __call__

python 8 檔案的輸入與輸出

檔案使用模式 r w 及 a 分別表示檔案的讀取,寫入和追加 而 r 表示以讀方式開啟。如果讀取的檔案中存在中文,則需要輸入如下內容,保證中文讀取正常 import sys reload sys sys.setdefaultencoding utf8 檔案的輸入 檔案內容讀取 read 將檔案中的所...

python基礎8之類的析構函式

析構函式,第一次聽說這個函式的名稱,那這個函式到底是幹嘛的呢?什麼才是析構函式吶?定義 在例項銷毀的時候呼叫的函式 2.1 定義 class dog object dog class def init self,name self.name name def sayhi self print the...

python之類與物件的屬性

在python2中的區分 經典類 class school pass 新式類 class school object pass 在python3中以上兩種均為新式類 屬性 注 類和物件均用點來訪問自己的屬性 資料屬性即變數,類的定義與函式又及其相似,其實可以用函式的作用域來理解類的屬性呼叫 類的資料...