Een echte instantie maken
Definieer Label als eenvoudige klasse en maak new_label(text). Geef een nieuwe Label-instantie met een eigen text-attribuut terug. Bewaar de tekst precies; een later nieuw kaartje mag een eerder kaartje niet wijzigen.
Een naamkaartje heeft tekst die je kunt lezen en aanpassen. Zodra je meerdere kaartjes gebruikt, wil je hun gegevens bij elkaar houden en duidelijk herkennen welk soort ding je voor je hebt. Je maakte in de vorige module al een eigen foutklasse; nu beschrijf je zelf gewone gegevensobjecten.
Een klasse beschrijft een soort object. Een instantie is een concreet exemplaar van die klasse. Met Card() vraag je een nieuw exemplaar van de klasse Card aan, zoals je met [] een nieuwe lijst maakt.
Een lege klassedefinitie kan voorlopig pass als inhoud hebben. De klasse heeft daarmee een geldig blok, ook al voeg je nog geen eigen gedrag toe. Je kunt daarna gegevens aan de gemaakte instantie hangen.
Zo'n benoemde eigenschap heet een attribuut. Met de puntnotatie card.name lees je het attribuut name van dat ene kaartje. Een toekenning zoals card.name = "Ada" bewaart de tekst bij de instantie waarnaar card verwijst.
Het voorbeeld maakt twee objecten en geeft ze ieder een eigen naam. Voorspel of het aanpassen van het eerste kaartje de naam op het tweede verandert. Let ook op de ronde haakjes bij iedere nieuwe instantie.
class Card:
pass
first = Card()
first.name = "Ada"
second = Card()
second.name = "Bo"
print(first.name, second.name)
first.name = "Ana"
print(first.name, second.name)Ada Bo Ana Bo
De variabelen bewaren verwijzingen naar de twee objecten. De namen van de variabelen zijn geen attribuutnamen: first kan bijvoorbeeld verwijzen naar een kaartje waarvan name de tekst Ada bevat. Je kiest die twee namen om verschillende dingen te beschrijven.
Dit is de situatie vóór de wijziging:
| Naam in het programma | Object | Attribuut name |
|---|---|---|
| first | Eerste kaartje | Ada |
| second | Tweede kaartje | Bo |
Deze tabel lijkt op het onderscheid tussen een lijst en de variabelen die naar haar verwijzen. Je nieuwe klasse verandert die verwijzingsregels niet. Zij geeft het object vooral een herkenbaar type en ruimte voor zijn eigen benoemde toestand.
Een toekenning alias = first maakt geen nieuw kaartje. Beide namen verwijzen dan naar dezelfde instantie. Dat wordt zichtbaar zodra je via één naam een attribuut wijzigt.
class Card:
pass
first = Card()
first.name = "Oud"
alias = first
alias.name = "Nieuw"
print(first.name)
print(alias.name)
print(first is alias)Nieuw Nieuw True
Gebruik is wanneer je wilt weten of twee verwijzingen hetzelfde object aanwijzen. Twee afzonderlijke kaartjes kunnen dezelfde tekst hebben en toch verschillende objecten zijn. Gelijkheid op basis van eigen gegevens komt later in deze module aan bod.
De naam Card verwijst naar de klasse zelf; Card() maakt een instantie. Een toekenning aan Card.name zet een waarde bij de klasse. Instanties zonder eigen name kunnen die gedeelde waarde zien, waardoor verschillende kaartjes onbedoeld dezelfde tekst krijgen.
Hang objectgebonden gegevens daarom aan de gemaakte instantie. In de opdrachten is Label het type en is bijvoorbeeld label één exemplaar. Met een nieuw Label() en daarna label.text = text geef je ieder kaartje een eigen attribuut.
Je schrijft gewone functies die met echte Label-instanties werken. new_label maakt een kaartje, read_label leest zijn tekst en rename verandert het meegegeven object. Die laatste functie geeft None terug; de verandering is zichtbaar via de bestaande verwijzing van de aanroeper.
two_labels maakt twee onafhankelijke objecten en geeft ze samen als tuple terug. Ook bij twee gelijke teksten moeten het twee kaartjes blijven. Bewaar tekst precies zoals ontvangen, inclusief lege tekst, spaties en Unicode; deze les voegt geen opschoonregel toe.
Definieer Label als eenvoudige klasse en maak new_label(text). Geef een nieuwe Label-instantie met een eigen text-attribuut terug. Bewaar de tekst precies; een later nieuw kaartje mag een eerder kaartje niet wijzigen.
Maak read_label(label) die de text van de ontvangen Label-instantie teruggeeft. Bewaar de inhoud inclusief lege tekst, spaties en Unicode. Laat het ontvangen object ongewijzigd.
Maak rename(label, text) die de text van dezelfde ontvangen instantie wijzigt en None teruggeeft. De aanroeper moet de wijziging via zijn bestaande verwijzing kunnen zien.
Maak two_labels(first, second) die twee afzonderlijke Label-instanties met de opgegeven teksten maakt en als tuple teruggeeft. Ook gelijke teksten horen bij twee verschillende objecten.
Hierna laat je nieuwe objecten hun beginwaarden zelf instellen met __init__.
Voer je code uit en ontdek
wat je hebt gemaakt.
Je hoeft het niet in één keer goed te doen. Na het uitvoeren zie je hier welke stappen al kloppen.