Python-descriptoren, of kortweg descriptoren, geven je een krachtige techniek om herbruikbare code te schrijven die je tussen klassen kunt delen. Ze lijken misschien op overerving, maar dat zijn ze technisch gezien niet. Het is een generieke manier om toegang tot attributen te onderscheppen. Descriptoren zijn het mechanisme achter properties, static methods, class methods, super-methods, enzovoort.
Descriptoren zijn toegevoegd in Python 2.2 en worden sindsdien gezien als iets magisch dat traditionele klassen een nieuwe stijl heeft gegeven. Het zijn klassen waarmee je beheerde eigenschappen in een andere klasse kunt maken. Concreet implementeren ze de interface voor de methoden __get__(), __set__() en __delete__(), wat ze om veel redenen interessant maakt. Denk bijvoorbeeld aan class- en property-decorators die je eerder in Python bent tegengekomen.
Eenvoudig gezegd: een klasse die voor een object de methode __get__(), __set()__ of __delete()__ implementeert, heet een "descriptor". Vrij naar de officiële Python-documentatie: een descriptor is een objectattribuut met binding behavior, waarbij de attribuuttoegang is overschreven door methoden uit het descriptorprotocol. Die methoden zijn __get__(), __set__() en __delete__() (Bron).
Binding behavior in de context van descriptoren betekent dat je vastlegt hoe een waarde kan worden gezet, opgevraagd (get) of verwijderd voor een bepaalde variabele, object of dataset. Deze hele interactie wordt gebonden aan dat stukje data, omdat het alleen geldt voor de data waarop je het hebt ingesteld, en dus alleen aan dat specifieke deel van de data is gekoppeld.
Descriptoren kunnen verder worden onderverdeeld in data- en niet-data-descriptoren. Als de descriptor die je schrijft alleen de methode __get__() heeft, is het een niet-data-descriptor; een implementatie die ook __set__() en __delete__() bevat, heet een data-descriptor. Niet-data-descriptoren zijn alleen leesbaar, terwijl data-descriptoren zowel lees- als schrijfbaar zijn.
Belangrijk om te onthouden: descriptoren worden toegewezen aan een klasse, niet aan een instantie van een klasse. Het aanpassen van de klasse overschrijft of verwijdert de descriptor zelf, in plaats van diens code te triggeren (IBM Developer).
Tot slot: de descriptorklasse is niet beperkt tot alleen deze drie methoden; hij kan ook andere attributen bevatten naast de methoden get, set en delete.
Laten we de methoden get, set en delete in meer detail bekijken, geïnspireerd door deze pagina van IBM Developer:
self is de instantie van de descriptor die je maakt (Real Python).
object is de instantie van het object waaraan je descriptor is gekoppeld (Real Python).
type is het type van het object waaraan de descriptor is gekoppeld (Real Python).
value is de waarde die wordt toegewezen aan het attribuut van de descriptor. get(self, object, type) set(self, object, value) delete(self, object)
__get__() benadert het attribuut of wanneer je informatie wilt opvragen. Het retourneert de waarde van het attribuut of werpt de uitzondering AttributeError als een gevraagd attribuut niet aanwezig is.
__set__() wordt aangeroepen bij een toewijzing aan een attribuut die de waarde van een attribuut zet. Retourneert niets, maar kan de uitzondering AttributeError werpen.
__delete__() stuurt een verwijderoperatie aan, d.w.z. wanneer je het attribuut van een object wilt verwijderen. Retourneert niets.
Laten we nu het doel van descriptoren begrijpen met behulp van enkele voorbeelden!
Doel van descriptoren
Laten we een klasse car definiëren met drie attributen: make, model en fuel_cap. Je gebruikt de methode __init__() om de attributen van de klasse te initialiseren. Vervolgens gebruik je de magische functie __str__(), die simpelweg de uitvoer retourneert van de drie attributen die je aan de klasse doorgeeft bij het maken van het object.
Let op: de methode __str__() retourneert de stringrepresentatie van het object. Deze wordt aangeroepen wanneer print() of de functie str() wordt gebruikt op een object van de klasse.
classCar:def__init__(self,make,model,fuel_cap):
self.make = make
self.model = model
self.fuel_cap = fuel_cap
def__str__(self):return"{0} model {1} with a fuel capacity of {2} ltr.".format(self.make,self.model,self.fuel_cap)Mogelijk gemaakt door
Wacht even, daar klopt iets niet, toch? De brandstofcapaciteit van een auto kan nooit negatief zijn. Toch accepteert Python dit zonder foutmelding. Dat komt omdat Python een dynamische programmeertaal is die geen expliciete typecontrole afdwingt.
Om dit te voorkomen, voegen we een if-voorwaarde toe in de methode __init__() en controleren we of de ingevoerde brandstofcapaciteit geldig is. Als de ingevoerde brandstofcapaciteit ongeldig is, werp dan een ValueError-exceptie.
classCar:def__init__(self,make,model,fuel_cap):
self.make = make
self.model = model
self.fuel_cap = fuel_cap
if self.fuel_cap <0:raise ValueError("Fuel Capacity can never be less than zero")def__str__(self):return"{0} model {1} with a fuel capacity of {2} ltr.".format(self.make,self.model,self.fuel_cap)Mogelijk gemaakt door
----------------------------------------ValueErrorTraceback(most recent call last)<ipython-input-22-1c3d23be72f7>in<module>---->1 car2 =Car("BMW","X7",-40)2print(car2)<ipython-input-20-1e154783588d>in__init__(self, make, model, fuel_cap)5 self.fuel_cap = fuel_cap
6if self.fuel_cap <0:---->7 raise ValueError("Fuel Capacity can never be less than zero")89 def __str__(self):ValueError: Fuel Capacity can never be less than zero
Mogelijk gemaakt door
Uit de bovenstaande uitvoer kun je opmaken dat alles voorlopig goed werkt, omdat het programma een ValueError werpt als de brandstofcapaciteit onder nul ligt.
Er is echter nog een mogelijk probleem: wat als de brandstofcapaciteit die je invoert een float of een string is? Niet alleen de brandstofcapaciteit, maar ook de make en model van de auto kunnen een geheel getal zijn. In al deze gevallen zal het programma geen exceptie werpen.
classCar:def__init__(self,make,model,fuel_cap):
self.make = make
self.model = model
self.fuel_cap = fuel_cap
if self.fuel_cap <0:raise ValueError("Fuel Capacity can never be less than zero")def__str__(self):return"{0} model {1} with a fuel capacity of {2} ltr.".format(self.make,self.model,self.fuel_cap)Mogelijk gemaakt door
Om ook het bovenstaande geval af te vangen, zou je kunnen denken aan nog een if-voorwaarde of het gebruik van de methode isinstance voor typecontrole.
Deze keer gebruiken we de ingebouwde methode isinstance om de fout af te handelen.
classCar:def__init__(self,make,model,fuel_cap):
self.make = make
self.model = model
self.fuel_cap = fuel_cap
ifisinstance(self.make,str):print(self.make)else:raise ValueError("Make of the car can never be an integer")if self.fuel_cap <0:raise ValueError("Fuel Capacity can never be less than zero")def__str__(self):return"{0} model {1} with a fuel capacity of {2} ltr.".format(self.make,self.model,self.fuel_cap)Mogelijk gemaakt door
----------------------------------------ValueErrorTraceback(most recent call last)<ipython-input-34-75b08cba454f>in<module>---->1 car2 =Car(-40,"X7",40)2print(car2)<ipython-input-31-175690bf3b98>in__init__(self, make, model, fuel_cap)7print(self.make)8else:---->9 raise ValueError("Make of the car can never be an integer")1011if self.fuel_cap <0:ValueError: Make of the car can never be an integer
Mogelijk gemaakt door
Mooi! Je hebt ook deze fout kunnen afhandelen.
Maar wat als je later expliciet de brandstofcapaciteit wilt wijzigen naar min 40? In dat geval werkt het niet, omdat de typecontrole alleen in de methode __init__() één keer wordt gedaan. Zoals je weet is __init__() een constructor en wordt deze slechts één keer aangeroepen wanneer je een object van de klasse maakt. Daarom zal de aangepaste typecontrole later falen.
Laten we dit begrijpen met een voorbeeld.
classCar:def__init__(self,make,model,fuel_cap):
self.make = make
self.model = model
self.fuel_cap = fuel_cap
ifisinstance(self.make,str):print(self.make)else:raise ValueError("Make of the car can never be an integer")if self.fuel_cap <0:raise ValueError("Fuel Capacity can never be less than zero")def__str__(self):return"{0} model {1} with a fuel capacity of {2} ltr.".format(self.make,self.model,self.fuel_cap)Mogelijk gemaakt door
Stel je nu voor dat je veel meer attributen hebt, zoals verbruik, prijs, accessoires, enz., die ook typecontrole vereisen, en dat je bovendien wilt dat sommige van deze attributen alleen leestoegang hebben. Dat zou toch best vervelend zijn?
Om al deze problemen aan te pakken, komen Python-descriptoren te hulp!
Zoals je hierboven hebt geleerd, heten klassen die de magische methoden __get__(), __set()__ of __delete()__ voor een object van het descriptorprotocol implementeren, descriptoren. Ze geven je ook extra controle over hoe een attribuut zich moet gedragen, bijvoorbeeld of het lees- of schrijfrechten moet hebben.
Laten we nu het bovenstaande voorbeeld uitbreiden door de Python-descriptormethoden toe te voegen.
classDescriptor:def__init__(self):
self.__fuel_cap =0def__get__(self, instance, owner):return self.__fuel_cap
def__set__(self, instance, value):ifisinstance(value,int):print(value)else:raise TypeError("Fuel Capacity can only be an integer")if value <0:raise ValueError("Fuel Capacity can never be less than zero")
self.__fuel_cap = value
def__delete__(self, instance):del self.__fuel_cap
Mogelijk gemaakt door
classCar:
fuel_cap = Descriptor()def__init__(self,make,model,fuel_cap):
self.make = make
self.model = model
self.fuel_cap = fuel_cap
def__str__(self):return"{0} model {1} with a fuel capacity of {2} ltr.".format(self.make,self.model,self.fuel_cap)Mogelijk gemaakt door
Maak je geen zorgen als de klasse Descriptor wat abstract lijkt. Laten we het opsplitsen in kleine stukjes en begrijpen wat elke methode doet.
De methode __init__() van de klasse Descriptor zet een lokale variabele __fuel_cap op nul. De dunder of dubbele underscore aan het begin betekent dat de variabele privé is. Die dubbele underscore is hier alleen bedoeld om het brandstofcapaciteitsattribuut van de klasse Descriptor te onderscheiden van dat van de klasse Car.
Zoals je nu weet, gebruik je de methode __get__() om attributen op te halen en hij retourneert de variabele brandstofcapaciteit. Hij neemt drie argumenten: het descriptorobject, de instantie van de klasse die het descriptorobject bevat, dus car2, en tenslotte de owner, de klasse waartoe de instantie behoort, dus de klasse Car. In deze methode retourneer je simpelweg de waarde van het attribuut, dus fuel_cap, waarvan de waarde is gezet in de methode __set__().
De methode __set__() wordt aangeroepen wanneer de waarde van het attribuut wordt gezet en, anders dan __get__(), retourneert hij niets. Hij heeft twee argumenten naast het descriptorobject zelf: de instance, hetzelfde als bij __get__(), en het argument value, de waarde die je aan het attribuut toekent. In deze methode controleer je of de waarde die je aan het attribuut fuel_cap wilt toekennen een geheel getal is. Zo niet, dan werp je een TypeError. Vervolgens controleer je in dezelfde methode ook of de waarde kleiner is dan nul; als dat zo is, werp je nog een exceptie, dit keer een ValueError. Na de controles werk je het attribuut fuel_cap bij naar de waarde.
Tot slot de methode __delete__(), die wordt aangeroepen wanneer het attribuut van een object wordt verwijderd en, net als __set__(), niets retourneert.
De klasse Car blijft verder hetzelfde als voorheen. De enige wijziging is dat je de instantie fuel_cap van de klasse Descriptor() toevoegt. Let op: zoals eerder vermeld moet de instantie van de descriptorklasse aan een klasse worden toegevoegd als klasseattribuut en niet als instantieattribuut.
Zodra je in de methode __init__() de lokale variabele fuel_cap toewijst aan de instantie fuel_cap, wordt de methode __set__() van de klasse Descriptor aangeroepen.
Laten we nu de brandstofcapaciteit naar een negatieve waarde veranderen en kijken of het programma een ValueError-exceptie werpt.
-40----------------------------------------ValueErrorTraceback(most recent call last)<ipython-input-115-1c3d23be72f7>in<module>---->1 car2 =Car("BMW","X7",-40)2print(car2)<ipython-input-107-3e1f3e97d3c7>in__init__(self, make, model, fuel_cap)4 self.make = make
5 self.model = model
---->6 self.fuel_cap = fuel_cap
78 def __str__(self):<ipython-input-106-0b252695aeed>in__set__(self, instance, value)1112if value <0:--->13 raise ValueError("Fuel Capacity can never be less than zero")1415 self.__fuel_cap = value
ValueError: Fuel Capacity can never be less than zero
Mogelijk gemaakt door
Als je je herinnert, hier mislukte de typecontrole toen je later de attribuutwaarde wijzigde naar een negatief getal, omdat de typecontrole slechts één keer gold in de methode __init__(). Laten we de waarde van fuel_cap nu bijwerken naar een string en kijken of dat een fout oplevert.
-1----------------------------------------ValueErrorTraceback(most recent call last)<ipython-input-120-dea9dbe96ebe>in<module>---->1 car2.fuel_cap =-1<ipython-input-106-0b252695aeed>in__set__(self, instance, value)1112if value <0:--->13 raise ValueError("Fuel Capacity can never be less than zero")1415 self.__fuel_cap = value
ValueError: Fuel Capacity can never be less than zero
Mogelijk gemaakt door
----------------------------------------TypeErrorTraceback(most recent call last)<ipython-input-121-0b316a9872c6>in<module>---->1 car2.fuel_cap ="BMW"<ipython-input-106-0b252695aeed>in__set__(self, instance, value)8print(value)9else:--->10 raise TypeError("Fuel Capacity can only be an integer")1112if value <0:TypeError: Fuel Capacity can only be an integer
Mogelijk gemaakt door
Perfect! Zoals je ziet werkt het ook wanneer je later het attribuut brandstofcapaciteit bijwerkt.
Er is echter een klein probleem met descriptoren: wanneer je een nieuwe of tweede instantie van de klasse maakt, wordt de waarde van de vorige instantie overschreven. De reden is dat descriptoren aan de klasse zijn gekoppeld en niet aan de instantie.
Laten we dit begrijpen met het onderstaande voorbeeld.
car3 = Car("BMW","X7",48)#created a new instance 'car3' with different valuesMogelijk gemaakt door
Deze tutorial was bedoeld voor iedereen die zich comfortabel voelt met Python en het gevorderde niveau wil beheersen. Als goede oefening kun je uitzoeken hoe je het probleem van het overschrijven van instanties, dat we vandaag bespraken, zou kunnen oplossen.
Stel gerust vragen over deze tutorial in de reacties hieronder.
Wil je meer leren over Python? Volg de volledige skill track Python Programming van DataCamp.
Duik in datawetenschap met Python en leer hoe je je data goed kunt analyseren en visualiseren. Je hoeft niet te kunnen programmeren of iets dergelijks.
Python-descriptoren, of kortweg descriptoren, geven je een krachtige techniek om herbruikbare code te schrijven die je tussen klassen kunt delen. Ze lijken misschien op overerving, maar dat zijn ze technisch gezien niet. Het is een generieke manier om toegang tot attributen te onderscheppen. Descriptoren zijn het mechanisme achter properties, static methods, class methods, super-methods, enzovoort.
Descriptoren zijn toegevoegd in Python 2.2 en worden sindsdien gezien als iets magisch dat traditionele klassen een nieuwe stijl heeft gegeven. Het zijn klassen waarmee je beheerde eigenschappen in een andere klasse kunt maken. Concreet implementeren ze de interface voor de methoden
__get__(),__set__()en__delete__(), wat ze om veel redenen interessant maakt. Denk bijvoorbeeld aan class- en property-decorators die je eerder in Python bent tegengekomen.Eenvoudig gezegd: een klasse die voor een object de methode
__get__(),__set()__of__delete()__implementeert, heet een "descriptor". Vrij naar de officiële Python-documentatie: een descriptor is een objectattribuut metbinding behavior, waarbij de attribuuttoegang is overschreven door methoden uit het descriptorprotocol. Die methoden zijn__get__(),__set__()en__delete__()(Bron).Binding behaviorin de context van descriptoren betekent dat je vastlegt hoe een waarde kan worden gezet, opgevraagd (get) of verwijderd voor een bepaalde variabele, object of dataset. Deze hele interactie wordtgebondenaan dat stukje data, omdat het alleen geldt voor de data waarop je het hebt ingesteld, en dus alleen aan dat specifieke deel van de data is gekoppeld.Descriptoren kunnen verder worden onderverdeeld in data- en niet-data-descriptoren. Als de descriptor die je schrijft alleen de methode
__get__()heeft, is het een niet-data-descriptor; een implementatie die ook__set__()en__delete__()bevat, heet een data-descriptor. Niet-data-descriptoren zijn alleen leesbaar, terwijl data-descriptoren zowel lees- als schrijfbaar zijn.Belangrijk om te onthouden: descriptoren worden toegewezen aan een klasse, niet aan een instantie van een klasse. Het aanpassen van de klasse overschrijft of verwijdert de descriptor zelf, in plaats van diens code te triggeren (IBM Developer).
Tot slot: de descriptorklasse is niet beperkt tot alleen deze drie methoden; hij kan ook andere attributen bevatten naast de methoden
get,setendelete.Laten we de methoden
get,setendeletein meer detail bekijken, geïnspireerd door deze pagina van IBM Developer:selfis de instantie van de descriptor die je maakt (Real Python).objectis de instantie van het object waaraan je descriptor is gekoppeld (Real Python).typeis het type van het object waaraan de descriptor is gekoppeld (Real Python).valueis de waarde die wordt toegewezen aan het attribuut van de descriptor. get(self, object, type) set(self, object, value) delete(self, object)__get__()benadert het attribuut of wanneer je informatie wilt opvragen. Het retourneert de waarde van het attribuut of werpt de uitzondering AttributeError als een gevraagd attribuut niet aanwezig is.__set__()wordt aangeroepen bij een toewijzing aan een attribuut die de waarde van een attribuut zet. Retourneert niets, maar kan de uitzondering AttributeError werpen.__delete__()stuurt een verwijderoperatie aan, d.w.z. wanneer je het attribuut van een object wilt verwijderen. Retourneert niets.Laten we nu het doel van descriptoren begrijpen met behulp van enkele voorbeelden!
Doel van descriptoren
Laten we een klasse
cardefiniëren met drie attributen:make,modelenfuel_cap. Je gebruikt de methode__init__()om de attributen van de klasse te initialiseren. Vervolgens gebruik je de magische functie__str__(), die simpelweg de uitvoer retourneert van de drie attributen die je aan de klasse doorgeeft bij het maken van het object.Let op: de methode
__str__()retourneert de stringrepresentatie van het object. Deze wordt aangeroepen wanneerprint()of de functiestr()wordt gebruikt op een object van de klasse.Zoals je in de bovenstaande uitvoer ziet, ziet alles er prima uit!
Laten we nu de brandstofcapaciteit van de auto wijzigen naar min 40.
Wacht even, daar klopt iets niet, toch? De brandstofcapaciteit van een auto kan nooit negatief zijn. Toch accepteert Python dit zonder foutmelding. Dat komt omdat Python een dynamische programmeertaal is die geen expliciete typecontrole afdwingt.
Om dit te voorkomen, voegen we een
if-voorwaarde toe in de methode__init__()en controleren we of de ingevoerde brandstofcapaciteit geldig is. Als de ingevoerde brandstofcapaciteit ongeldig is, werp dan een ValueError-exceptie.Uit de bovenstaande uitvoer kun je opmaken dat alles voorlopig goed werkt, omdat het programma een
ValueErrorwerpt als de brandstofcapaciteit onder nul ligt.Er is echter nog een mogelijk probleem: wat als de
brandstofcapaciteitdie je invoert een float of een string is? Niet alleen de brandstofcapaciteit, maar ook demakeenmodelvan de auto kunnen een geheel getal zijn. In al deze gevallen zal het programma geen exceptie werpen.Om ook het bovenstaande geval af te vangen, zou je kunnen denken aan nog een
if-voorwaarde of het gebruik van de methodeisinstancevoor typecontrole.Deze keer gebruiken we de ingebouwde methode
isinstanceom de fout af te handelen.Mooi! Je hebt ook deze fout kunnen afhandelen.
Maar wat als je later expliciet de brandstofcapaciteit wilt wijzigen naar min 40? In dat geval werkt het niet, omdat de typecontrole alleen in de methode
__init__()één keer wordt gedaan. Zoals je weet is__init__()een constructor en wordt deze slechts één keer aangeroepen wanneer je een object van de klasse maakt. Daarom zal de aangepaste typecontrole later falen.Laten we dit begrijpen met een voorbeeld.
En kijk: je hebt de typecontrole kunnen omzeilen.
Stel je nu voor dat je veel meer attributen hebt, zoals verbruik, prijs, accessoires, enz., die ook typecontrole vereisen, en dat je bovendien wilt dat sommige van deze attributen alleen
leestoegang hebben. Dat zou toch best vervelend zijn?Om al deze problemen aan te pakken, komen Python-descriptoren te hulp!
Zoals je hierboven hebt geleerd, heten klassen die de magische methoden
__get__(),__set()__of__delete()__voor een object van het descriptorprotocol implementeren, descriptoren. Ze geven je ook extra controle over hoe een attribuut zich moet gedragen, bijvoorbeeld of het lees- of schrijfrechten moet hebben.Laten we nu het bovenstaande voorbeeld uitbreiden door de Python-descriptormethoden toe te voegen.
Maak je geen zorgen als de klasse Descriptor wat abstract lijkt. Laten we het opsplitsen in kleine stukjes en begrijpen wat elke methode doet.
__init__()van de klasse Descriptor zet een lokale variabele__fuel_capop nul. Dedunderof dubbele underscore aan het begin betekent dat de variabele privé is. Die dubbele underscore is hier alleen bedoeld om het brandstofcapaciteitsattribuut van de klasse Descriptor te onderscheiden van dat van de klasse Car.__get__()om attributen op te halen en hij retourneert de variabele brandstofcapaciteit. Hij neemt drie argumenten: het descriptorobject, de instantie van de klasse die het descriptorobject bevat, duscar2, en tenslotte de owner, de klasse waartoe de instantie behoort, dus de klasseCar. In deze methode retourneer je simpelweg de waarde van het attribuut, dusfuel_cap, waarvan de waarde is gezet in de methode__set__().__set__()wordt aangeroepen wanneer de waarde van het attribuut wordt gezet en, anders dan__get__(), retourneert hij niets. Hij heeft twee argumenten naast het descriptorobject zelf: de instance, hetzelfde als bij__get__(), en het argument value, de waarde die je aan het attribuut toekent. In deze methode controleer je of de waarde die je aan het attribuutfuel_capwilt toekennen een geheel getal is. Zo niet, dan werp je eenTypeError. Vervolgens controleer je in dezelfde methode ook of de waarde kleiner is dan nul; als dat zo is, werp je nog een exceptie, dit keer eenValueError. Na de controles werk je het attribuutfuel_capbij naar de waarde.__delete__(), die wordt aangeroepen wanneer het attribuut van een object wordt verwijderd en, net als__set__(), niets retourneert.De klasse
Carblijft verder hetzelfde als voorheen. De enige wijziging is dat je de instantiefuel_capvan de klasseDescriptor()toevoegt. Let op: zoals eerder vermeld moet de instantie van de descriptorklasse aan een klasse worden toegevoegd als klasseattribuut en niet als instantieattribuut.Zodra je in de methode
__init__()de lokale variabelefuel_captoewijst aan de instantiefuel_cap, wordt de methode__set__()van de klasse Descriptor aangeroepen.Laten we nu de brandstofcapaciteit naar een negatieve waarde veranderen en kijken of het programma een ValueError-exceptie werpt.
Als je je herinnert, hier mislukte de typecontrole toen je later de attribuutwaarde wijzigde naar een negatief getal, omdat de typecontrole slechts één keer gold in de methode
__init__(). Laten we de waarde van fuel_cap nu bijwerken naar een string en kijken of dat een fout oplevert.Perfect! Zoals je ziet werkt het ook wanneer je later het attribuut brandstofcapaciteit bijwerkt.
Er is echter een klein probleem met descriptoren: wanneer je een nieuwe of tweede instantie van de klasse maakt, wordt de waarde van de vorige instantie overschreven. De reden is dat descriptoren aan de klasse zijn gekoppeld en niet aan de instantie.
Laten we dit begrijpen met het onderstaande voorbeeld.
Wanneer je de instantie
car2afdrukt, zul je zien dat de waarden zijn overschreven doorcar3.Conclusie
Gefeliciteerd met het afronden van de tutorial.
Deze tutorial was bedoeld voor iedereen die zich comfortabel voelt met Python en het gevorderde niveau wil beheersen. Als goede oefening kun je uitzoeken hoe je het probleem van het overschrijven van instanties, dat we vandaag bespraken, zou kunnen oplossen.
Stel gerust vragen over deze tutorial in de reacties hieronder.
Wil je meer leren over Python? Volg de volledige skill track Python Programming van DataCamp.
Bekijk ook onze Python Functions-tutorial.