簡體   English   中英

使用類創建對象,為什么我需要__init __(self,args):?

[英]Creating objects with classes, why do I need __init__(self, args):?

很抱歉發布這樣一個奇怪的問題,通常當我感到困惑時,我只是“隨身攜帶”,直到我有一個頓悟,然后將其排除,但是調用def __init__(self):在我的課堂內似乎完全是多余的,似乎離開它out也適用:

class Pet(object):
    type_of_pet = ""
    number_of_legs = 0
    name = ""

讓我創建:

fred = pet()
fred.type_of_pet = "alligator"

就像我要把類更改為:

class Pet(object):
    def __init__(self):
         type_of_pet = ""

alice = Pet()
alice.type_of_pet = "Pterodactyl" 

我只是不明白為什么我需要__init__而這里的其他線程並不像我希望的那樣清晰。 有什么我可以做到這個“點擊”?

將賦值語句放在類定義中不會聲明實例屬性; 它設置類屬性。 如果您這樣做,所有寵物將共享相同的nametype_of_petnumber_of_legs

除其他外, __init__用於設置實例屬性:

def __init__(self, type_of_pet, name, number_of_legs):
    self.type_of_pet = type_of_pet
    self.name = name
    self.number_of_legs = number_of_legs

這將在實例上設置屬性,而不是類,因此每個對象都有自己的名稱,類型和腿數。

在創建類的每個實例后立即調用__init__ 這是進行實例級初始化的正確位置。

您的type_of_pet和第一個示例中定義的其他屬性是類級信息。 該表單聲明Pet類本身具有type_of_pet值,並且該值存在於與您可能定義的任何方法相同的級別。

當您檢查實例的名稱時,如果有實例,它將獲得分配給該實例的值,如果沒有,則轉到類級別。 所以這:

fred = Pet()
print fred.type_of_pet

實際上檢查類本身的type_of_pet

賦值將僅修改您實際調用它的對象,因此這將在實例級別設置一個值:

fred.type_of_pet = 'alligator'

這不會對類進行任何更改,只需將名稱type_of_pet的值放入fred實例中即可。 因此,將類級別定義用作實例的默認值是很常見的。

但是這會讓你陷入困境的是像list這樣的可變類型。 這不符合您的期望:

class Pet:
    vaccinations = []

fido = Pet()
fido.vaccinations.append('rabies')

因為fido.vaccinations最終是對類級別定義的單個列表的引用。 相反,你會使用__init__給每只寵物一個獨立的列表。

就個人而言,我越來越相信使用類級別屬性作為不可變類型的默認值會產生更多的混淆,而且應該只保存在真正應該在類級而不是每個實例上跟蹤的內容。 但那是意見。

__init__是一種構造函數,當創建類的實例時,python在實例化期間調用__init__()來定義在實例化類時應該發生的其他行為,基本上為該對象設置一些起始值或運行例程實例化時需要。

來源)

例如,您可以將Pet類更改為:

class Pet(object):
    def __init__(self, type_of_pet):
         self.type_of_pet = type_of_pet

並創建一個新實例:

alice = Pet("Pterodactyl")

如果在__init__函數之外初始化類變量,則每個實例都將共享該值。 這對於靜態類很有用,但我認為你不希望在“普通”類上使用這種行為。

順便說一下,你不能在__init__使用type_of_pet="" ,它必須是self.type_of_pet=""

當你在實例化后可以在類上分配屬性時,你會問為什么需要__init__()

答案是,所以你可以在實例化對象時傳遞屬性值,就像你應該的那樣。 這不僅可以節省您的打字; 實例化后在類上分配屬性容易出錯:如果你不小心分配給number_off_legs而不是number_of_legs怎么辦? 這本身不是一個錯誤,因為屬性可能被命名為任何東西,但它會導致其他代碼(期望number_of_legs )失敗,或者在您的情況下,獲取錯誤的數據(因為類的默認值將在此處使用)點)。 此外,如果您需要更改屬性名稱,該名稱將遍布您的代碼,因此您需要在很多地方更改它。

因此,為了避免這些麻煩,您需要編寫一個創建對象的小函數,然后在其上分配屬性,並在將對象返回給您之前執行任何其他必要的初始化(打開文件,創建從屬對象等) 。 這是你的__init__()方法,Python有助於將它附加到你的類,以便你可以實例化對象並一次傳入屬性值。 當你只是存儲一些數據時它似乎沒有用,但是當你的類變得更復雜時,你會發現它非常方便。

當您直接在類中定義成員時,這些成員將成為類本身的一部分,而不是類的實例的一部分。 您仍然可以通過實例訪問它們,但每個實例都沒有自己的實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM