python erkennt meine attribute nicht

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
nichtSoGuter
User
Beiträge: 92
Registriert: Mittwoch 13. April 2022, 17:40

Ich habe einen code geschrieben, welches aus einem json file die Konfigurationen rauslesen und in den attributen der Klasse Config abspeichern soll. leider werden die Attribute aber nicht erkannt. Ich erhalte den error: AttributeError: type object 'Config' has no attribute 'data'

Der Code dazu lautet:

Code: Alles auswählen

class Config:
    """Config class contains data, train, model hyperparameter"""
    def __init__(self, data, train, model):
    	# FRAGE: Hier sind doch die Attribute festegelegt?? --> wieso erkennt python die attribute nicht?
        self.data = data
        self.train = train
        self.model = model

    @classmethod
    def from_json(cls, cfg):
        """Creates config from json und initalisiert die Klasse """
        json_formatierter_string = json.dumps(cfg) #Serialize obj to a JSON formatted STRING (kein JSON sondern nur so formatiert)
        params = json.loads(json_formatierter_string, object_hook=HelperObject) # deserialize JSON to a Python object
            # object_hook: JSON string is passed to the callback function (=HelperObject)as a dict
        return cls(data=params.data, train=params.train, model = params.model)

class HelperObject():
    """Helper class to convert json into Python object"""
    def __init__(self, dict_passed_from_object_hook):
        self.__dict__.update(dict_passed_from_object_hook)
            #__dict__: contains all defined attributes of an object;
            #.update(): updates dictionary with elements

# zum testen des Codes übergebe ich der Klasse eine erfundenen input
dummy_eingabe= {
    "model":{
        "input":[1,2,3],
        "output":3 ,
        "bool": True
    },
    "data":{
        "key1": "key2"
    },
    "train":{
        "keykey":"okey"
    }
}

Config.from_json(cfg=dummy_eingabe)

Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Liegt sicher an deiner Kraut und Rüben Einrückung
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nichtSoGuter: Ich kann das Problem nicht nachvollziehen, bei mir funktioniert das soweit, also es gibt kein AttributeError bei dem gezeigten Code.

Ist aber irgendwie etwas umständlich den Weg über JSON zu gehen. Es gibt für so etwas — verpacken von Wörterbüchern in Objekte mit Attributen — auch schon fertige Lösungen. Zum Beispiel das `addict`-Modul.

Der Methodenname und der Kommentar in der Klassenmethode sind auch falsch. a) `from_json()` bekommt gar kein JSON sondern ein Python-Wörterbuch, und b) entgegen dem Kommentar „(kein JSON sondern nur so formatiert)“ ist das JSON und nicht nur so formatiert.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist grober Unfug, die Datenstruktur, die du übergeben hast, erstmal in einen String zu “Dumpen”, um sie dann wieder in die gleiche Datenstruktur zu laden. Und JSON ist das Format. Nicht die Datenstruktur. Die ist Python.

Dein HelperObject ist nahezu nutzlos und sollte durch normale dict Zugriffe ersetzt werden.

Zu deinem Problem: der Fehler passt nicht zum Code. Der wird bei mir - abgesehen vom fehlenden import - ohne Murren ausgeführt.
nichtSoGuter
User
Beiträge: 92
Registriert: Mittwoch 13. April 2022, 17:40

Ich habe den code aus einem Buch. (um den code hier angeben zu können, habe ich den code aber ein wenig verändert)
Ich habe leider auch nicht wirklich verstanden wieso zuerst json.dumps und dann json.loads verwendet wurde.
Zuerst wird ein json erstellt, dann wird dieser in ein python objekt umgewandelt. Daher war ich bisschen verwirrt und dachte, dass json.dumps vllt keinen json sondern nur das format eines jsons erstellt


@__deets__
Wieso ist HelperObject nutzlos? Und was sind dict_ zugriffe? Bzw. hast du einen Link dazu wo ich etwas zu dict_ zugriffen lesen kann?
Vielen Dank im Voraus
Zuletzt geändert von nichtSoGuter am Mittwoch 20. Juli 2022, 16:19, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

JSON *ist* ein Format. Nichts anderes. Der Satz "keinen json sondern nur das format eines jsons erstellt" ist also sinnlos. Man kann JSON aus Datenstrukturen erstellen, und Datenstrukturen aus JSON. Weil es ein Format ist, das bestimmte Datentypen und Datenstrukuturen (listen, dicts, numbers, strings, bools, None) darstellen kann.

Was auch immer das fuer ein Buch ist, das scheint nicht so dolle.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

was noch dazu kommt ist, dass JSON sich ja sehr gut auf Python Datenstrukturen abbilden lässt, also JSON Object -> Python Dict und JSON Array -> Python List.

Der Zugriff in HelperObject auf __dict__ ist echt komisch - dass man direkt auf __dict__ eines Objects zugeifen muss / will, kommt eigentlich so gut wie nie vor.

Gruß, noisefloor
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@noisefloor das ist ein ehemals recht beliebtes pattern, Bunch genannt. Dadurch soll der etwas ausfuehrlichere Operator-Zugriff

etwas["schluessel"]

durch

etwas.schluessel

ersetzt werden. Ist ein bisschen ueberkandidelt, aber kann man machen.
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn ich so etwas brauche und das externe `addict` nicht in Frage kommt, benutze ich `types.SimpleNamespace` aus der Standardbibliothek für so etwas.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
das ist ein ehemals recht beliebtes pattern, Bunch genannt. Dadurch soll der etwas ausfuehrlichere Operator-Zugriff
Ok, Danke für die Info. Habe ich bis zu diesem Thread noch nie irgendwo gesehen oder gelesen... Wann war denn "damals"? ;-)

Gruß, noisefloor
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Puh, ich glaube so Anfang/Mitte der Nuller Jahre habe ich das durch Alex Martelli und sein Python in a Nutshell bzw. Beitraegen in comp.lang.python kennengelernt. Heutzutage wuerde man sowas eher mit dataclasses machen denke ich mal, weil es doch sehr implizit ist. Persoenlich habe ich es entsprechend lange nicht mehr genutzt.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Ok, dass war kurz bevor ich mit Python angefangen habe. Bzw. wenn war ich damals noch nicht so weit, dass ich das gebraucht hätte.

Gruß, noisefloor
nichtSoGuter
User
Beiträge: 92
Registriert: Mittwoch 13. April 2022, 17:40

Vielen Dank nochmal für eure Hilfe.
Dank euch habe ich endlich einen Code den ich auch verstehe:-)

Code: Alles auswählen

class HerauslesenHyperparameter():
    @staticmethod
    def aus_json(data):
        return Dict(json.loads(data))
    
    @staticmethod
    def aus_py_dict(data):
        return Dict(data)
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nichtSoGuter: Das sollte aber keine Klasse sein. Klassen sind keine Behälter/Namensräume für einfache Funktionen. Dafür sind Module vorgesehen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten