Erzeugen einer Klasse + Erzeugen einr Methode, die die Attribute des Objekts als String zurückgibt

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
Lini
User
Beiträge: 26
Registriert: Freitag 13. November 2020, 00:39

Hallo,

ich löse Aufgabe:

Erzeugen Sie eine Klasse beliebiger geometrischer Figur. Die Ausgabe der erzeugten Klasse soll die Attribute (als Argumente) der Figur zurückgeben.
Jeder Objekt/Figur musste über Attribute verfügen, die von der ausgewählten Form abhängen. Bei einem Rechteck sind dies beispielsweise die Argumente x, y, width und height.

Außerdem müssen Sie diese Attribute beim Erstellen eines Objekts der Klasse übergeben können.

Erstellen Sie eine Methode, die die Attribute Ihrer Form als Zeichenfolge zurückgibt.

Verwenden Sie str für die Implementierung. Für ein "Rechteck"-Objekt mit den Attributwerten x = 5, y = 10, Breite = 50, Höhe = 100 sollte die Methode beispielsweise die Zeichenfolge Rectangle (5, 10, 50, 100) zurückgeben.



Ich habe es versucht, die Code zu schreiben, aber meine jetzige Variante gibt die Zeichenfolge Rectangle (5, 10, 50, 100) nicht zurück. Was ich jetzt geschrieben habe:

Code: Alles auswählen

#  Erzeugen Sie eine Klasse beliebiger geometrischer Figure. Die Ausgabe der erzeugten Klasse soll die Attribute (als Argumente) der Figur zurückgeben.
#  Jede Objekt (Figur) muss über Attribute verfügen, die von der ausgewählten Form abhängen. Bei einem Rechteck sind dies beispielsweise die Argumente x, y, width und height.

class Rechtangle: 
	def __init__(self, x, y, width, height): 
		self.x = x 
		self.y = y 
		self.width = width 
		self.height = height

# Erzeugen Sie eine Methode, die die Attribute Ihrer Form als Zeichenfolge (str) zurückgibt.

    def atributs_as_string(self):
        return str(self.x, self.y, self.width, self.height) 


# Außerdem müssen Sie diese Attribute beim Erstellen eines Objekts der Klasse übergeben können.

recht_1 = Rechtangle(5, 10, 50, 100)     # wir erzeugen Objakt recht_1

print(recht_1.atributs_as_string)
Ich bitte um Hilfe und Korrektur.
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du brauchst dafür String Formatting (Stichwort: f-Strings) und die __repr__()-Methode. Und je nachdem wie du es lösen willst, ggf. auch type(). Googeln musst du aber selber. ;)

Von str() würde ich in diesem Fall abraten. Das macht die Sache bloß komplizierter.
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Lini: Korrektur wäre als erstes mal, das es `attributes` und nicht `atributs` heisst. Wobei man den Zusatz auch weglassen kann, denn `as_string()` wäre für eine Methode, die das gesamte Objekt in eine Zeichenkettenrepräsentation überführt, als Name aussagekräftig genug.

Ein weiterer Rechtschreiberror ist `Rechtangle`. Also entweder `Rectangle` oder `Rechteck`, aber bitte kein Denglisch, und das auch noch in *einem* Wort.

Dann wäre das aber auch nicht der übliche Name für so eine Methode, denn genau für diese Art von Darstellung ist die `repr()`-Funktion gedacht, die mit der `__repr__()`-Methode zusammenspielt. Und die `__str__()`-Methode von `object` greift auch auf `__repr__()` zu, das heisst man hat damit auch automatisch die `str()`-Funktion und allgemein Umwandlung eines Objekts in einer Zeichenkette, beispielsweise bei `print()`, mit abgedeckt.

Namen bitte auch nicht kryptisch abkürzen und mit irgendwelchen Nummern versehen. Wenn man `rectangle` (oder `rechteck`) meint, sollte man nicht `recht_1` schreiben, sondern `rectangle` (oder `rechteck`).

Dann wäre es hilfreich wenn Du auch verraten würdest was nicht so funktioniert wie Du Dir das gedacht hast. Ich hätte ja erst gedacht Du müsstest eine Fehlermeldung bekommen, die Dich weiter bringt — bis mir dann der Fehler aufgefallen ist der dafür sorgt, dass Du die Fehlermeldung nicht bekommst.

Also was hast Du bei dem Code erwartet das passiert, und was ist denn dann tatsächlich passiert, und was daran verstehst Du nicht?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Lini
User
Beiträge: 26
Registriert: Freitag 13. November 2020, 00:39

__blackjack__ hat geschrieben: Sonntag 19. Dezember 2021, 04:20 @Lini: .................................

Dann wäre es hilfreich wenn Du auch verraten würdest was nicht so funktioniert wie Du Dir das gedacht hast. Ich hätte ja erst gedacht Du müsstest eine Fehlermeldung bekommen, die Dich weiter bringt — bis mir dann der Fehler aufgefallen ist der dafür sorgt, dass Du die Fehlermeldung nicht bekommst.

Also was hast Du bei dem Code erwartet das passiert, und was ist denn dann tatsächlich passiert, und was daran verstehst Du nicht?
Herzlichen Dank für Ihre Tipps und fürs "Beleuchtung des Tunnels". Ihre Kommentare sind sehr nutzlich, ich versuche es zu verdauen.

meine jetzige Variante gibt die Zeichenfolge Rectangle (5, 10, 50, 100) nicht zurück. Und es gab keine Fehlermeldungen.
Lini
User
Beiträge: 26
Registriert: Freitag 13. November 2020, 00:39

__blackjack__ hat geschrieben: Sonntag 19. Dezember 2021, 04:20 @Lini:

Dann wäre das aber auch nicht der übliche Name für so eine Methode, denn genau für diese Art von Darstellung ist die `repr()`-Funktion gedacht, die mit der `__repr__()`-Methode zusammenspielt. Und die `__str__()`-Methode von `object` greift auch auf `__repr__()` zu, das heisst man hat damit auch automatisch die `str()`-Funktion und allgemein Umwandlung eines Objekts in einer Zeichenkette, beispielsweise bei `print()`, mit abgedeckt.
Ich denke zu diesem Absatz benötigte ich bisschen mehr Visualisierung:
- gleichnamigen `repr()`-Funktion gedacht, die mit der `__repr__()`-Methode zusammenspielt
- Und die `__str__()`-Methode von `object` greift auch auf `__repr__()`


So könnte es funktionieren:

Code: Alles auswählen

    def __str__(self):
        return 'Rectangle({}, {}, {}, {})'.format(self.a, self.b, self.width, self.height)
aber ganz ehrlich: so was habe ich eher gefunden als konstruiert, obwohl verstanden
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Lini: Na das ist es doch schon fast. Nur halt ``def __repr__(self):`` statt ``def __str__(self):``. Und ich würde statt dem `format()`-Aufruf ein f-Zeichenkettenliteral machen und bei den Platzhaltern noch ``!r`` hinzufügen, oder einen `repr()`-Aufruf für jeden Wert der da eingefügt wird. Und man könnte `Rectangle` noch ”variabler” gestalten in dem man das da nicht hart rein schreibt, sondern den Namen der Klasse ermittelt.

Code: Alles auswählen

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.x!r}, {self.y!r},"
            f" {self.width!r}, {self.height!r})"
        )
Wenn man dann irgendwann keine Lust mehr so etwas dauernd selbst zu schreiben, gibt es so etwas wie das `attrs`-Package:

Code: Alles auswählen

#!/usr/bin/env python3
from attr import attrib, attrs


@attrs
class Rectangle:
    x = attrib()
    y = attrib()
    width = attrib()
    height = attrib()


def main():
    rectangle = Rectangle(5, 10, 50, 100)
    print(rectangle)


if __name__ == "__main__":
    main()
Ausgabe:

Code: Alles auswählen

Rectangle(x=5, y=10, width=50, height=100)
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Oder halt mit dem dataclasses-Modul, welches Python bereits mitliefert:

Code: Alles auswählen

#!/usr/bin/env python3
from dataclasses import dataclass


@dataclass
class Rectangle:
    x: int
    y: int
    width: int
    height: int


def main():
    rectangle = Rectangle(5, 10, 50, 100)
    print(rectangle)


if __name__ == "__main__":
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Joah, ich will aber Anfängern nicht gleich falsche Typannotationen näher bringen. ``int``? ``float`` geht nicht? Und warum sollten `decimal.Decimal` oder `fractions.Fraction` aus der Standardbibliothek nicht gehen? Und was ist mit `pint.Unit` wenn man nicht nur eine Zahl sondern auch eine Einheit wie Zentimeter haben möchte? `uncertainties.UFloat` anyone? Oder irgendwas zahliges aus Numpy?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für das Beispiel reicht es jedenfalls. Wenn man das allgemeiner machen möchte, könnte man das numbers-Modul bemühen.

https://docs.python.org/3/library/numbe ... ers.Number
Antworten