Klassenattribut als Verweis auf Objekt dieser Klasse

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Ernst Haft
User
Beiträge: 7
Registriert: Samstag 19. März 2022, 15:02

Hallo liebes Python-Forum.

Ich sitze gerade über einer Programmierung von Klassen und möchte wissen:
Ist es möglich, in einer Klasse Attribute zu erstellen, die auf weitere Objekte derselben Klasse verweisen?
Ich möchte nämlich eine Art Straßenkarte mit Wegpunkten erstellen. "Wegpunkt" ist eine Klasse. Jedes Objekt dieser Klasse soll wissen, an wie viele und an welche Objekte dieser Klasse es grenzt.

Ist das so mit Python realisierbar? Wenn nicht, welche Alternativen gibt es?

Viele liebe Grüße :wink: ,
euer Ernst
Benutzeravatar
sparrow
User
Beiträge: 4237
Registriert: Freitag 17. April 2009, 10:28

Klar, warum sollte das nicht gehen?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das waere zB eine klassisch doppelt verlinkte Liste. Oder man wuerde den Wegpunkten einen Verweis auf die gesamte Liste mitgeben, so das der sich darin selbst lokalisieren und die jeweiligen Nachbarn finden kann. Wahrscheinlich lohnt sich dabei sogar die Einfuehrung eines Path-Objektes, statt nur einer Liste, aber fuer den Anfang reichts.

Code: Alles auswählen



class Waypoint:

    def __init__(self, coordinate, waypoints):
        self.coordinate = coordinate
        self._waypoints = waypoints
        self._index = None

    @property
    def index(self):
        if self._index is None:
            self._index = self._waypoints.index(self)
        return self._index

    @property
    def next(self):
        try:
            return self._waypoints[self.index + 1]
        except IndexError:
            return None

    def __repr__(self):
        return f"{self.__class__.__name__} {self.coordinate}"


def main():
    waypoints = []
    for i in range(100):
        waypoints.append(Waypoint((i, i**2), waypoints))
    some_waypoint = waypoints[37]
    print(some_waypoint, some_waypoint.next)


if __name__ == '__main__':
    main()
Benutzeravatar
snafu
User
Beiträge: 6751
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wobei das mit .next etwas ungewöhnlich ist. Ich würde stattdessen die entsprechende Dunder-Methode benutzen:

Code: Alles auswählen

#!/usr/bin/env python3
class Waypoint:
    def __init__(self, coordinate, waypoints):
        self.coordinate = coordinate
        self._waypoints = waypoints
        self._index = None

    def __repr__(self):
        return f"{type(self).__name__} {self.coordinate}"

    def __next__(self):
        try:
            return self._waypoints[self.index + 1]
        except IndexError:
            return None

    @property
    def index(self):
        if self._index is None:
            self._index = self._waypoints.index(self)
        return self._index


def main():
    waypoints = []
    for i in range(100):
        waypoints.append(Waypoint((i, i**2), waypoints))
    some_waypoint = waypoints[37]
    print(some_waypoint, next(some_waypoint))


if __name__ == "__main__":
    main()
Sirius3
User
Beiträge: 17826
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: __next__-Methoden findet man nur bei Iteratoren, und zum vollständigen Iterator fehlt noch die __iter__-Methode und sowieso die Tatsache, dass das Objekt etwas iteriert. Deine __next__-Methode wirft auch keine StopIteration-Exception, sondern gibt immer nur den selben Wert zurück.
Benutzeravatar
Ernst Haft
User
Beiträge: 7
Registriert: Samstag 19. März 2022, 15:02

Hallo Forum.
Ich habe den Code von __deets__ in Verwendung.
Was jedoch macht der folgende Teil der Programmierung?

Code: Alles auswählen

def main():
    waypoints = []
    for i in range(100):
        waypoints.append(Waypoint((i, i**2), waypoints))
    some_waypoint = waypoints[37]
    print(some_waypoint, some_waypoint.next)


if __name__ == '__main__':
    main()
Wie kommen die Zahlen 100 (Zeile 3) und 37 (Zeile 5) zustande?
Vielen Dank für das Einsenden des Codes.
Viele Grüße,
euer Ernst. :)
Benutzeravatar
__blackjack__
User
Beiträge: 13241
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Ernst Haft: Die hat sich __deets__ ausgedacht. Kannst auch 42 und 23 nehmen. 😎
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
Benutzeravatar
Ernst Haft
User
Beiträge: 7
Registriert: Samstag 19. März 2022, 15:02

@Ernst Haft: Die hat sich __deets__ ausgedacht. Kannst auch 42 und 23 nehmen.
42 - die Antwort auf alles ;-)

Aber hat der Code sonst noch irgendeinen Sinn, welcher sich mir momentan nicht erschließt?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es sind Beispielzahlen. Es ist ja auch kein echter Pfad von Wegpunkten. Warum wundert dich das nicht?
Benutzeravatar
snafu
User
Beiträge: 6751
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich finde das auch komisch. Wenn man immer die waypoints mit übergeben muss, dann ergibt die Klasse für mich wenig Sinn. Für mich sieht das nach einer sehr komplizierten Art aus, um an i+1 zu kommen. Welchen Mehrwert hat dieser Weg anstatt einfach ganz normal über die Liste zu iterieren...?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das heißt aber, dass du an der Stelle wo du einen Weg Punkt hast auch immer die Liste der Wegpunkte vorhalten musst. Kann man machen. Oder die eben dem Wegpunkt mitgeben.
Antworten