5 svar
125 visningar
Qetsiyah 6503 – Livehjälpare
Postad: 19 jan 2023 18:15

Ha koll på alla instanser av en klass för att kunna loopa igenom dem

Hej, jag vill kunna spara alla instanser av en klass för att vid behov loopa igenom dem. Jag har tänkt mig något sånt här:

class CarManager:
	def __init__(self):
		self.registry = []


class Car:
	def __init_(self):
		
		# Saker som hastighet, position, färg
		
		carlist.registry.append(self) # Rapportera till en instans av CarManager att en ny bil har skapats. Varje element i listan ska peka på en bil.


Men när jag googlar "iterate over all instances of a class" eller "keep track of all instances of a class" så kommer folk med konstiga lösningar jag inte förstår, är inte min kod också ok?

https://stackoverflow.com/questions/739882/iterating-over-object-instances-of-a-given-class-in-python

https://stackoverflow.com/questions/71528171/how-to-iterate-through-the-objects-of-a-class

Fermatrix 7841 – Fd. Medlem
Postad: 19 jan 2023 19:23

För att kunna iterera över objekt så behöver man för en klass iterable. Det är främst det som de två länkarna du hänvisar till pratar om. 

vad är carlist för något som du kallar i konstruktorn till car?

Jag tippar på att det du vill ha är en klass CarManager som du kan kalla på en metod för att konstruera en Car och lägga till i listan?


Jag antar att du menar något i följande stil typ:

class CarManager:
    def __init__(self):
        self.registry = []

    def add_car(self, aCar):
        self.registry.append(aCar)

    def printCar(self):
        for item in self.registry:
            print(item)

    def printCarVariantTwo(self):
        for item in self.registry:
            for param in item:
                print(f'we are now iterating over a car object!: {param}')


class Car:
    def __init__(self, param1, param2, param3):
        self.param1 = param1
        self.param2 = param2
        self.param3 = param3

    def __repr__(self):
        return str(self.__dict__)

    def __iter__(self):
        return iter([self.param1, self.param2, self.param3])


cm = CarManager()
c1 = Car(1, 2, 3)
c2 = Car(2, 3, 4)
cm.add_car(c1)
cm.add_car(c2)
cm.printCar()
cm.printCarVariantTwo()

Och det går. Du kan även ta emot alla parametrar i en funktion i CarManager och lägga till en ny instans av Car om du vill det i listan.

Jag är också osäker om du vet var det betyder att göra en klass itererbar (kanske jag inte förstod vad som förvirrade dig) men jag gjorde car iterable. 

Helt enkelt, för att loopa över ett objekt måste den vara iterable, att du kan skriva for i in list: är bara för att objektet list är iterable. Om du nu försöker loopa över en Car objekt enligt ovan så får du ett av elementen i taget.

Laguna 28587
Postad: 19 jan 2023 20:05

Din lösning är nog helt i sin ordning.

Iteratorer är ett helt oberoende begrepp som är bra i många sammanhang. Så det är bra att lära sig dem i vilket fall som helst.

Fermatrix 7841 – Fd. Medlem
Postad: 19 jan 2023 20:46 Redigerad: 19 jan 2023 20:48

Är denna förklaringen förståelig?

https://www.geeksforgeeks.org/python-difference-iterable-iterator/

Det är också viktigt att inte blanda ihop en iterator och något som är en iterable.

Detta är inte helt trivialt. Jag lärde mig detta först när jag lärde mig generics i Java. Vet inte riktigt när det borde komma i en Python kurs. 


Jag missade också vad din kommentar verkligen avsåg, men ja, man kan lösa det på många olika sätt beroende på specifikationerna och syftet med programmet.

Hondel 1294
Postad: 19 jan 2023 21:30

Kanske att istället för att explicit kalla carlist.registry.append kanske du skulle kunna i klassen CarManager skapa en funktion addCar(self, car) som gör detta (och kalla denna funktion i  Car-construktorn). Om du i framtiden ändrar hur du sparar bilarna i CarManager så kan du bara ändra i addCar, och slipper ändra överallt i koden som kallar registry.append :)

Hondel 1294
Postad: 20 jan 2023 10:36 Redigerad: 20 jan 2023 10:39

Ett sätt att sedan iterera över alla bilar i CarManager är att implementera metoden __iter__ som bara returnerar iter(self.registry). Du kan då skriva saker som

for car in manager

och liknande. 

Edit: jag hade uppenbarligen inte läst igenom tidigare svaren ordentligt så mitt svar var kanske helt onödigt, men men, 

Svara Avbryt
Close