Seite 1 von 1

Objekt Eigenschaften iterieren

Verfasst: Freitag 5. Februar 2021, 22:19
von Sternenregen
Guten Abend,

ich habe eine Klasse geschrieben die eine Liste und ein Dictionary enthält. Dieses Objekt habe ich dem Template_Renderer übergeben. Nun möchte ich die Properties des Objektes iterieren.

Leider funktioniert es nicht so einfach wie mit:

Code: Alles auswählen

{% for item in object.list %}
Leider haben die Lösungen die ich gefunden habe nichts gebracht.

Mein Ziel ist es einfach den Inhalt der Liste in HTML in einer Table auszugeben.

Gruß

Re: Objekt Eigenschaften iterieren

Verfasst: Freitag 5. Februar 2021, 22:20
von __deets__
Dann zeig doch mal deine Klasse.

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 09:46
von Sternenregen
Ja, ich schätze da liegt das Problem. Ich bin erst vor kurzen auf Python umgestiegen und knabbern noch an der Umgewöhnung.

Die Klasse sieht so aus:

Die Klasse sieht jetzt bereits anders aus, als zu dem Zeitpunkt, als ich es gestern gepostet habe. Ich bekomm allerdings jetzt
die Fehlermeldung:

Code: Alles auswählen

HudInterface' object has no attribute '_HudInterface__products'
Ich erkenne den Fehler gerade nicht in der Syntax und warum er sagt, dass das Attribute nicht existiert. Ich dachte ich habe
diese mit self__products = [] beispielsweise initialisiert. Über die Get und Methoden arbeite ich dann mit den Eigenschaften.
Nebenbei gesagt ich möchte einen parameterlosen Konstrukt.

Code: Alles auswählen

class foo:

    def __int__(self):
        self.__products = []
        self.__matches_count = {}

    def add_product(self, value):
        self.__products.append(value)

    def add_match(self, key):
        if key not in self.__matches_count:
            self.__matches_count[key] = 1
        else:
            self.__matches_count[key] += 1

    def get_products(self):
        return self.__products

    def get_matches(self):
        return self.__matches_count


Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 10:02
von __deets__
Gewöhn dir mal sofort ab, __ und getter zu benutzen. Das ist NICHT wofür du denkst das es ist, produziert den Fehler den du bekommst, und getter sind unnötiger Boilerplate, den man in Python nicht schreibt. Wenn ein Attribut zur öffentlichen Schnittstelle gehört, dann hat das einfach keinen unterstrich, geschweige denn zwei.

Für deinen count Mechanismus gibt es collections.Counter, oder collections.defaultdict.

Und bitte beachte PEP8 für Benamungen.

Code: Alles auswählen

from collections import Counter

class Foo:

    der __init__(self):
        self.products = []
        self.matches_count = Counter()

    def add_product(self, value):
        self.products.append(value)

    def add_match(self, key):
        self.matches_count[key] += 1
Ich finde auch die zwei Funktionalitäten in einer Klasse etwas fragwürdig. SOLID und so.

Mit dem Template hat das aber alles nicht viel zu tun. Wenn du iterieren willst über dir Produkte,musst du natürlich objekt.attribut schreiben.

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 10:06
von Sirius3
Doppelte Unterstriche sind nur sehr selten sinnvoll.
In Deinem Fall brauchst Du gar keine Unterstriche, weil sowohl products als auch matches oder matches_count öffentlich sind, durch die trivialen Getter, die man in Python nicht benutzt, weil man genauso gut direkt auf die Attribute zugeifen kann.
Bleibt also

Code: Alles auswählen

class Foo:
    def __int__(self):
        self.products = []
        self.matches_count = {}

    def add_product(self, value):
        self.products.append(value)

    def add_match(self, key):
        if key not in self.matches_count:
            self.matches_count[key] = 1
        else:
            self.matches_count[key] += 1
Mit einem defaultdict, wird add_match auch noch simple:

Code: Alles auswählen

from collections import defaultdict

class Foo:
    def __int__(self):
        self.products = []
        self.matches_count = defaultdict(int)

    def add_product(self, value):
        self.products.append(value)

    def add_match(self, key):
        self.matches_count[key] += 1

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 10:22
von __deets__
@Sirius3: zwei unabhängige Lösungen die im diff nur eine Zeile haben (mit dem 👁 geschätzt), hatten wir auch noch nicht so oft 😁

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 11:51
von Sternenregen
Vielen Dank euch beiden :)

Bin vor kurzen erst auf Python gewechselt und die Umstellung fällt mir irgendwie schwerer als gedacht.

Code: Alles auswählen

Ich finde auch die zwei Funktionalitäten in einer Klasse etwas fragwürdig. SOLID und so. 

Mit dem Template hat das aber alles nicht viel zu tun. Wenn du iterieren willst über dir Produkte,musst du natürlich objekt.attribut schreiben.
[/quote]



Danke für den Tipp. Ich habe die Klassennamen, Properties etc abgeändert bevor ich es gepostet habe.

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 12:12
von Sternenregen
Ich hab es jetzt gerade mal getestet.

Ich habe es so geschrieben wie ihr es gesagt habt. Ich hab nach wie vor den gleichen Fehler.

Das Objekt initialisiere ich wie folgt:

Code: Alles auswählen

meinObjekt = foo()
Über eine schleife füge ich der Objektliste Items hinzu:

Code: Alles auswählen

meinObjekt.add_product(object)

Es kommt nach wie vor die Meldung

Code: Alles auswählen

object has no attribute 'products '
:?:

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 12:19
von Sirius3
Bitte den gesamten Code und die komplette Fehlermeldung posten. Mit diesen Fragmenten kann man nichts anfangen.

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 12:24
von Sternenregen

Code: Alles auswählen

from collections import defaultdict

class Foo:
    def __int__(self):
        self.products = []
        self.matches_count = defaultdict(int)

    def add_product(self, value):
        self.products.append(value)

    def add_match(self, key):
        self.matches_count[key] += 1



from bar import Foo


def some_method():
	meinObjekt = Foo()
	
	for product in result:
		meinObjekt.add_product(product)
	

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 12:35
von Sirius3
Manchmal muß man schon genau hinschauen. Es heißt __init__ und nicht __int__.

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 12:36
von Sternenregen
Sternenregen hat geschrieben: Samstag 6. Februar 2021, 12:24

Code: Alles auswählen

from collections import defaultdict

class Foo:
    def __int__(self):
        self.products = []
        self.matches_count = defaultdict(int)

    def add_product(self, value):
        self.products.append(value)

    def add_match(self, key):
        self.matches_count[key] += 1



from bar import Foo


def some_method():
	meinObjekt = Foo()
	
	for product in result:
		meinObjekt.add_product(product)
	

Hier die Fehlermeldung:

Code: Alles auswählen

AttributeError:  'Foo' object has no attribute 'products'

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 12:50
von __deets__
Das kommt davon, wenn du Code kopierst oder irgendwie Beispiel zusammenschreibst, die nicht funktionieren. Statt echten Code und echte Fehlermeldungen zu zeigen. Wie jetzt auch, ich musste results einfügen, die Funktion (nicht Methode) aufrufen, und den sinnlosen Import entfernen. Und dann habe ich genau EINEN Buchstaben hinzugefügt, und es geht. Schau mal genau hin

Code: Alles auswählen

from collections import defaultdict

class Foo:
    def __init__(self):
        self.products = []
        self.matches_count = defaultdict(int)

    def add_product(self, value):
        self.products.append(value)

    def add_match(self, key):
        self.matches_count[key] += 1



def some_method():
	meinObjekt = Foo()
	result = [1]
	for product in result:
		meinObjekt.add_product(product)
		
some_method()

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 13:16
von Sternenregen
Beruhige dich :)

Gut, das i hatte gefehlt. Das i hatte übrigends auch in meinem richtigen Code gefehlt und nicht in dem hier reingepasteten und abgeänderten Code. Ein dummer Fehler.

Der Import ist meines Erachtens keineswegs sinnlos, da ich in einer anderen Pythondatei das Objekt erstelle. Dachte das wäre anhand des Imports ersichtlich. Ich werde es beim nächsten Mal berücksichtigen und näher erläutern.
Zudem dachte ich, dass es selbsterklärend ist, dass wenn ich etwas iteriere, dass da eine entsprechende Variable dafür vorhanden sein muss.

Aber ich werde das nächste mal meinen richtigen Code posten.

Danke vielmals.

Re: Objekt Eigenschaften iterieren

Verfasst: Samstag 6. Februar 2021, 13:45
von Sirius3
Es geht hier nicht um *den* richtigen Code, sondern um richtigen Code, der lauffähig ist, zumindest soweit, dass er den Fehler zeigt und nicht bei einem anderen Fehler hängen bleibt. Der Import ist zum Verstehen des Fehlers gar nicht nötig.