Ce este __init__ în Python? [With Examples]

Doriți să începeți cu designul orientat pe obiecte în Python? Faceți primii pași astăzi, învățând despre metoda __init__ a lui Python.

În acest tutorial, vom trece peste elementele de bază ale claselor și obiectelor Python, apoi vom continua să învățăm despre metoda __init__.

Până la sfârșitul acestui tutorial, veți putea răspunde la următoarele întrebări:

  • Ce sunt variabilele de instanță sau atributele de instanță?
  • Cum ajută metoda init la inițializarea atributelor instanței?
  • Cum putem seta valori implicite pentru atribute?
  • Cum putem folosi metodele clasei ca constructori pentru a crea obiecte?

Să începem.

Clase și obiecte Python

Clasele sunt fundamentale pentru programarea orientată pe obiecte în Python. Putem crea o clasă și defini atribute și metode – pentru a lega împreună datele și funcționalitățile asociate.

Odată ce am creat o clasă, o putem folosi ca model (sau șablon) pentru a crea obiecte (instanțe).

👩‍🏫 Exemplu de timp! Să creăm o clasă Employee în care fiecare obiect al acestei clase are următoarele atribute:

  • nume_complet: numele complet al angajatului în formatul prenume prenume
  • emp_id: ID-ul angajatului
  • departament: departamentul căruia îi aparțin
  • experiență: numărul de ani de experiență pe care îl au

Ce înseamnă acest lucru? 🤔

Fiecare angajat individual va fi o instanță sau obiect al clasei Angajat. Și fiecare obiect va avea propria sa valoare pentru full_name, emp_id, departament și experiență.

Aceste atribute se mai numesc și variabile de instanță și vom folosi termenii atribute și variabile de instanță în mod interschimbabil.

Vom ajunge să adăugăm atribute în curând. Deocamdată creăm o clasă de angajați astfel:

class Employee:
    pass

Folosirea pass (ca substituent) ne ajută să evităm erorile atunci când rulăm scriptul.

Deși versiunea actuală a clasei Employee nu este foarte utilă, este totuși o clasă validă. Astfel, putem crea obiecte din clasa Employee:

employee_1 = Employee()

print(employee_1)
#Output: <__main__.Employee object at 0x00FEE7F0>

De asemenea, putem adăuga atribute și le inițializam cu valori așa cum se arată:

employee_1.full_name="Amy Bell"
employee_1.department="HR"

Dar această abordare de a adăuga atribute de instanță este atât ineficientă, cât și predispusă la erori. De asemenea, acest lucru nu permite utilizarea clasei ca șablon pentru a crea obiecte. Iată unde ajută metoda __init__.

Înțelegerea rolului metodei __init__ într-o clasă Python

Ar trebui să putem inițializa variabilele de instanță atunci când instanțiem un obiect și metoda __init__ ne ajută să facem asta. Metoda __init__ este apelată de fiecare dată când este creat un nou obiect al clasei pentru a inițializa valorile variabilelor de instanță.

  Cum să vizualizați, să editați și să adăugați metadate la o fotografie

Dacă ați programat într-un limbaj precum C++, veți vedea că metoda __init__ funcționează similar cu constructorii.

Definirea metodei __init__

Să adăugăm metoda __init__ la clasa Employee:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience

Parametrul self se referă la instanța clasei, iar self.attribute inițializează atributul instanței la valoarea din partea dreaptă.

Acum putem crea obiecte astfel:

employee_2 = Employee('Bella Joy','M007','Marketing',3)
print(employee_2)
# Output: <__main__.Employee object at 0x017F88B0>

Când tipărim obiectele angajat, nu primim nicio informație utilă, cu excepția clasei căreia îi aparțin. Să adăugăm o metodă __repr__ care definește un șir de reprezentare pentru clasă:

 def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Adăugând __repr__ la clasa Employee, avem:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Acum obiectele angajat au un șir de reprezentare util:

print(employee_2)
# Output: Bella Joy,M007 from Marketing with 3 years of experience.

Unele convenții

Înainte de a continua, iată câteva note:

  • Am folosit self ca prim parametru în metoda __init__ pentru a face referire la instanța clasei în sine și am folosit self.attribute_name pentru a inițializa diferitele atribute. Folosirea self-ului este convenția preferată (puteți folosi orice alt nume totuși).
  • Când definim metoda __init__, setăm numele parametrilor din definițiile __init__ pentru a se potrivi cu numele atributelor. Acest lucru îmbunătățește lizibilitatea.

Cum să adăugați valori implicite pentru atribute

În exemplul pe care l-am codificat până acum, toate atributele sunt necesare. Crearea obiectelor de sens are succes numai dacă trecem valorile pentru toate câmpurile către constructor.

Încercați să instanțiați un obiect al clasei Employee fără a trece valoarea pentru atributul experiență:

employee_3 = Employee('Jake Lee','E001','Engineering')

Veți primi următoarea eroare:

Traceback (most recent call last):
  File "main.py", line 22, in <module>
    employee_3 = Employee('Jake Lee','E001','Engineering')
TypeError: __init__() missing 1 required positional argument: 'experience'

Dar dacă doriți să faceți anumite atribute opționale, puteți face acest lucru furnizând valori implicite pentru acele atribute atunci când definiți metoda __init__.

Aici oferim o valoare implicită de 0 pentru atributul experiență:

class Employee:
    def __init__(self, full_name,emp_id,department,experience=0):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Obiectul employee_3 este creat fără valoare pentru atributul experiență; valoarea implicită de 0 este utilizată pentru experiență.

employee_3 = Employee('Jake Lee','E001','Engineering')
print(employee_3.experience)
# Output: 0

Constructori de clasă alternativi folosind metode de clasă

Până acum am văzut doar cum să definim metoda __init__ și să setăm valorile implicite pentru atribute atunci când este necesar. De asemenea, știm că trebuie să transmitem valorile pentru atributele necesare în constructor.

  Top 6 certificări pentru a te face un manager mai bun

Uneori, totuși, valorile pentru aceste variabile de instanță (sau atribute) pot fi disponibile într-o structură de date diferită, cum ar fi un tuplu, un dicționar sau un șir JSON.

Deci ce facem?

Să luăm un exemplu. Să presupunem că avem valori ale variabilei de instanță într-un dicționar Python:

dict_fanny = {'name':'Fanny Walker','id':'H203','dept':'HR','exp':2}

Putem accesa dicționarul și obținem toate atributele astfel:

name = dict_fanny['name']
id = dict_fanny['id']
dept = dict_fanny['dept']
exp = dict_fanny['exp']

După aceasta, puteți crea un obiect trecând aceste valori la constructorul de clasă:

employee_4 = Employee(name, id, dept, exp)
print(employee_4)
# Output: Fanny Walker,H203 from HR with 2 years of experience.

Amintiți-vă: trebuie să faceți acest lucru pentru fiecare obiect nou pe care îl creați. Această abordare este ineficientă și cu siguranță putem face mai bine. Dar cum?

În Python, putem folosi metodele clasei ca constructori pentru a crea obiecte ale clasei. Pentru a crea o metodă de clasă folosim decoratorul @classmethod.

Să definim o metodă care analizează dicționarul, obține valorile variabilei de instanță și le folosește pentru a construi obiecte Employee.

    @classmethod
    def from_dict(cls,data_dict):
        full_name = data_dict['name']
        emp_id = data_dict['id']
        department = data_dict['dept']
        experience = data_dict['exp']
        return cls(full_name, emp_id, department, experience)

Când trebuie să creăm obiecte folosind date din dicționar, putem folosi metoda clasei from_dict().

💡 Observați utilizarea cls în metoda clasei în loc de self. Așa cum folosim self pentru a ne referi la instanță, cls este folosit pentru a ne referi la clasă. De asemenea, metodele de clasă sunt legate de clasă și nu de obiecte.

Deci, atunci când apelăm metoda clasei from_dict() pentru a crea obiecte, o apelăm în clasa Employee:

emp_dict = {'name':'Tia Bell','id':'S270','dept':'Sales','exp':3}
employee_5 = Employee.from_dict(emp_dict)
print(employee_5)
# Output: Tia Bell,S270 from Sales with 3 years of experience.

Acum, dacă avem un dicționar pentru fiecare dintre cei n angajați, putem folosi metoda clasei from_dict() ca constructor pentru a instanția în obiecte – fără a fi nevoie să preluăm valorile variabilelor instant din dicționar.

📝O notă despre variabilele clasei

Aici am definit metoda clasei care este legată de clasă și nu instanțe individuale. Similar metodelor de clasă, putem avea și variabile de clasă.

  Cum să utilizați certificatul de recompensă GameStop online

Ca și metodele de clasă, variabilele de clasă sunt legate de clasă și nu de o instanță. Când un atribut ia o valoare fixă ​​pentru toate instanțele clasei, putem lua în considerare definirea acestora ca variabile de clasă.

Întrebări frecvente

1. De ce aveți nevoie de metoda __init__ în Python?

Metoda __init__ dintr-o definiție de clasă ne permite să inițializam atributele sau variabilele de instanță ale tuturor instanțelor clasei. Metoda __init__ este apelată de fiecare dată când este creată o nouă instanță a clasei.

2. Puteți avea mai multe metode __init__ într-o clasă Python?

Scopul de a avea mai multe metode __init__ într-o clasă Python este de a oferi mai mulți constructori care instanțiază obiecte. Dar nu puteți defini mai multe metode __init__. Dacă definiți mai multe metode __init__, a doua și cea mai recentă implementare o vor suprascrie pe prima. Cu toate acestea, puteți utiliza decoratorul @classmethod pentru a defini metode de clasă care pot fi folosite ca constructori pentru a instanția obiecte.

3. Ce se întâmplă dacă nu definiți metoda __init__ într-o clasă?

Dacă nu definiți metoda __init__, puteți încă să instanțiați obiecte. Cu toate acestea, va trebui să adăugați manual variabile de instanță și să atribuiți valori fiecăruia dintre ele. Nu veți putea transmite valorile pentru variabilele de instanță în constructor. Acest lucru nu este doar predispus la erori, dar și înfrânge scopul de a avea clasa ca un plan din care putem instanția obiecte.

4. Puteți avea valori implicite pentru argumente în metoda __init__?

Da, este posibil să furnizați valori implicite pentru unul sau mai multe atribute atunci când definiți metoda __init__. Furnizarea valorilor implicite ajută la ca aceste atribute să fie opționale în constructor. Atributele iau valorile implicite atunci când nu trecem valorile pentru aceste atribute în constructor.

5. Puteți modifica atributele în afara metodei __init__?

Da, puteți actualiza oricând valoarea unui atribut în afara metodei __init__. De asemenea, puteți adăuga în mod dinamic atribute noi la o instanță după ce ați creat o anumită instanță.

Concluzie

În acest tutorial, am învățat cum să folosim metoda __init__ pentru a inițializa valorile variabilelor de instanță. Deși acest lucru este simplu, poate fi repetitiv, mai ales atunci când aveți o mulțime de atribute.

Dacă sunteți interesat, puteți explora modulul dataclasses. În Python 3.7 și versiunile ulterioare, puteți utiliza modulul de clase de date încorporat pentru a crea clase de date care stochează date. Pe lângă implementările implicite ale __init__ și alte metode utilizate în mod obișnuit; vin cu o mulțime de caracteristici interesante pentru indicii de tip, valori implicite complexe și optimizare.

Apoi, aflați mai multe despre dacă __name__==’__main__’ în Python.