Hva er __init__ i Python? [With Examples]

Ønsker du å komme i gang med objektorientert design i Python? Ta de første stegene i dag ved å lære om Pythons __init__-metode.

I denne opplæringen går vi over det grunnleggende om Python-klasser og -objekter, og fortsetter for å lære om __init__-metoden.

Ved slutten av denne opplæringen vil du kunne svare på følgende spørsmål:

  • Hva er instansvariabler eller instansattributter?
  • Hvordan hjelper init-metoden med å initialisere instansattributtene?
  • Hvordan kan vi angi standardverdier for attributter?
  • Hvordan kan vi bruke klassemetoder som konstruktører for å lage objekter?

La oss komme i gang.

Python-klasser og -objekter

Klasser er grunnleggende for objektorientert programmering i Python. Vi kan lage en klasse og definere attributter og metoder – for å binde sammen data og tilhørende funksjonalitet.

Når vi har opprettet en klasse, kan vi bruke den som en blåkopi (eller en mal) for å lage objekter (forekomster).

👩‍🏫 Eksempel på tid! La oss lage en Employee-klasse der hvert objekt i denne klassen har følgende attributter:

  • fullt_navn: det fulle navnet på den ansatte i formatet fornavn etternavn
  • emp_id: ansatt-ID
  • avdeling: avdelingen de tilhører
  • erfaring: antall års erfaring de har

Hva betyr dette? 🤔

Hver enkelt ansatt vil være en forekomst eller et objekt av klassen Ansatt. Og hvert objekt vil ha sin egen verdi for full_name, emp_id, department og experience.

Disse attributtene kalles også forekomstvariabler, og vi vil bruke begrepene attributter og forekomstvariabler om hverandre.

Vi kommer til å legge til attributter om litt. Foreløpig oppretter vi en medarbeiderklasse slik:

class Employee:
    pass

Å bruke pass (som plassholder) hjelper oss å unngå feil når vi kjører skriptet.

Selv om den nåværende versjonen av Employee-klassen ikke er veldig nyttig, er den fortsatt en gyldig klasse. Så vi kan lage objekter av Employee-klassen:

employee_1 = Employee()

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

Vi kan også legge til attributter og initialisere dem med verdier som vist:

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

Men denne tilnærmingen til å legge til instansattributter er både ineffektiv og utsatt for feil. Dette tillater heller ikke bruk av klasse som en mal for å lage objekter. Her er hvor __init__-metoden hjelper.

  14 beste SMS-markedsføringsplattformer for å engasjere brukerne dine

Forstå rollen til __init__-metoden i en Python-klasse

Vi bør være i stand til å initialisere forekomstvariablene når vi instansierer et objekt, og __init__-metoden hjelper oss med det. __init__-metoden kalles hver gang et nytt objekt i klassen opprettes for å initialisere verdiene til instansvariablene.

Hvis du har programmert i et språk som C++, vil du se at __init__-metoden fungerer på samme måte som konstruktører.

Definere __init__-metoden

La oss legge til __init__-metoden til Employee-klassen:

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

Self-parameteren refererer til forekomsten av klassen, og self.attribute initialiserer forekomstattributtet til verdien på høyre side.

Vi kan nå lage objekter som slik:

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

Når vi skriver ut de ansattes objekter, får vi ingen nyttig informasjon bortsett fra klassen de tilhører. La oss legge til en __repr__ metode som definerer en representasjonsstreng for klassen:

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

Når vi legger til __repr__ til Employee-klassen, har vi:

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."

Nå har medarbeiderobjektene en nyttig representasjonsstreng:

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

Noen konvensjoner

Før vi går videre, her er et par merknader:

  • Vi brukte self som den første parameteren i __init__-metoden for å referere til selve klasseforekomsten og brukte self.attribute_name for å initialisere de ulike attributtene. Å bruke selv er den foretrukne konvensjonen (du kan imidlertid bruke et hvilket som helst annet navn).
  • Når vi definerer __init__-metoden, setter vi parameternavnene i __init__-definisjonene til å samsvare med navnene på attributtene. Dette forbedrer lesbarheten.

Slik legger du til standardverdier for attributter

I eksemplet vi har kodet så langt, er alle attributtene påkrevd. Det betyr at objektoppretting er vellykket bare hvis vi sender inn verdiene for alle feltene til konstruktøren.

Prøv å instansiere et objekt av klassen Employee uten å gi inn verdien for erfaringsattributtet:

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

Du får følgende feilmelding:

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'

Men hvis du vil gjøre visse attributter valgfrie, kan du gjøre det ved å angi standardverdier for disse attributtene når du definerer __init__-metoden.

  12 beste globale delte hosting for nybegynnere

Her gir vi en standardverdi på 0 for opplevelsesattributtet:

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."

Employer_3-objektet opprettes uten verdi for erfaringsattributtet; standardverdien 0 brukes for erfaring.

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

Alternative klassekonstruktører som bruker klassemetoder

Så langt har vi bare sett hvordan du definerer __init__-metoden og setter standardverdier for attributter når det er nødvendig. Vi vet også at vi må sende inn verdiene for de nødvendige attributtene i konstruktøren.

Noen ganger kan imidlertid verdiene for disse forekomstvariablene (eller attributtene) være tilgjengelige i en annen datastruktur, for eksempel en tuppel, en ordbok eller en JSON-streng.

Så hva gjør vi?

La oss ta et eksempel. Anta at vi har verdier av instansvariabelen i en Python-ordbok:

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

Vi kan trykke inn i ordboken og få alle attributtene slik:

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

Etter dette kan du lage et objekt ved å sende inn disse verdiene til klassekonstruktøren:

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

Husk: du må gjøre dette for hvert nytt objekt du lager. Denne tilnærmingen er ineffektiv, og vi kan definitivt gjøre det bedre. Men hvordan?

I Python kan vi bruke klassemetoder som konstruktører for å lage objekter av klassen. For å lage en klassemetode bruker vi @classmethod-dekoratoren.

La oss definere en metode som analyserer ordboken, henter instansvariabelverdiene og bruker dem til å konstruere Employee-objekter.

    @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)

Når vi trenger å lage objekter ved hjelp av data fra ordboken, kan vi bruke klassemetoden from_dict().

💡 Legg merke til bruken av cls i klassemetoden i stedet for selv. Akkurat slik vi bruker selv for å referere til instansen, brukes cls for å referere til klassen. Klassemetoder er også bundet til klassen og ikke objekter.

Så når vi kaller klassemetoden from_dict() for å lage objekter, kaller vi den på Employee-klassen:

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.

Hvis vi nå har en ordbok for hver av de n ansatte, kan vi bruke klassemetoden from_dict() som en konstruktør for å instansiere i objekter – uten å måtte hente de øyeblikkelige variabelverdiene fra ordboken.

  Slik sletter du kontakter fra iPhone

📝En merknad om klassevariabler

Her definerte vi klassemetoden som er bundet til klassen og ikke individuelle forekomster. I likhet med klassemetoder kan vi også ha klassevariabler.

Som klassemetoder er klassevariabler bundet til klassen og ikke en forekomst. Når et attributt har en fast verdi for alle forekomster av klassen, kan vi vurdere å definere dem som klassevariabler.

Vanlige spørsmål

1. Hvorfor trenger du __init__-metoden i Python?

__init__-metoden i en klassedefinisjon lar oss initialisere attributtene eller forekomstvariablene til alle forekomster av klassen. __init__-metoden kalles hver gang en ny forekomst av klassen opprettes.

2. Kan du ha flere __init__-metoder i en Python-klasse?

Målet med å ha flere __init__-metoder i en Python-klasse er å gi flere konstruktører som instansierer objekter. Men du kan ikke definere flere __init__-metoder. Hvis du definerer flere __init__-metoder, vil den andre og den nyeste implementeringen overskrive den første. Du kan imidlertid bruke @classmethod-dekoratoren til å definere klassemetoder som kan brukes som konstruktører for å instansiere objekter.

3. Hva skjer hvis du ikke definerer __init__-metoden i en klasse?

Hvis du ikke definerer __init__-metoden, kan du fortsatt instansiere objekter. Du må imidlertid legge til forekomstvariabler manuelt og tilordne verdier til hver av dem. Du vil ikke kunne sende inn verdiene for instansvariablene i konstruktøren. Dette er ikke bare utsatt for feil, men motvirker også hensikten med å ha klassen som en blåkopi som vi kan instansiere objekter fra.

4. Kan du ha standardverdier for argumenter i __init__-metoden?

Ja, det er mulig å angi standardverdier for ett eller flere attributter når du definerer __init__-metoden. Å gi standardverdier bidrar til å gjøre disse attributtene valgfrie i konstruktøren. Attributtene tar standardverdiene når vi ikke sender inn verdiene for disse attributtene i konstruktøren.

5. Kan du endre attributter utenfor __init__-metoden?

Ja, du kan alltid oppdatere verdien til et attributt utenfor __init__-metoden. Du kan også legge til nye attributter dynamisk til en forekomst etter at du har opprettet den bestemte forekomsten.

Konklusjon

I denne opplæringen lærte vi hvordan du bruker __init__-metoden for å initialisere verdiene til forekomstvariabler. Selv om dette er enkelt, kan det være repeterende – spesielt når du har mange attributter.

Hvis du er interessert, kan du utforske dataklassemodulen. I Python 3.7 og nyere kan du bruke den innebygde dataklassemodulen til å lage dataklasser som lagrer data. I tillegg til standardimplementeringer av __init__ og andre ofte brukte metoder; de kommer med mange kule funksjoner for typetips, komplekse standardverdier og optimalisering.

Deretter kan du lære mer om if __name__==’__main__» i Python.