Leere Argumente, Default Argumente

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
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Zeig doch einfach den Code wie er wirklich ist, insbesondere die Stelle, wo du `initialisieren` aufrufst.
TobiM
User
Beiträge: 15
Registriert: Mittwoch 10. März 2021, 09:06

Ich habe einmal eine base Datei, ehrlich gesagt keine Ahnung wofür ich die genau brauche, aber es wurde nicht in der Hauptdatei akzeptiert.

Code: Alles auswählen

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# ORM and Db Connection
engine = create_engine('postgresql://postgres:passwort1234@localhost:5432/test', echo=False)
Session = sessionmaker(bind=engine)
Base = declarative_base()
Dann die Hauptdatei, hierbei habe ich für bessere Lesbarkeit Klassennamen und Attribute leicht verändert:

Code: Alles auswählen


#Imports
from sqlalchemy import create_engine
from sqlalchemy import event
from sqlalchemy.orm import mapper
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, String, Integer, Date
from base import Base


#Class Hierachy
class Lebewesen(Base):
    __tablename__ = 'Tierwelt'
    id = Column(Integer, primary_key=True)
    name = Column(String(100))
    maximalKraft = Column(Integer)
    alter = Column(Integer)
    type = Column(String(150))
    
    __mapper_args__ = {
        'polymorphic_identity':'Lebewesen',
        'polymorphic_on':type
    }
    
class Tier(Lebewesen):
    __mapper_args__ = {'polymorphic_identity':'Tier'}
    
    
class Hund(Tier):
    anzahlPfoten = Column(Integer)
    __mapper_args__ = {'polymorphic_identity':'Hund'}
    

class Labrador(Hund):  
    __mapper_args__ = {'polymorphic_identity':'Labrador'}
    
    
    #Konsturtor, alle default auf none
    def __init__(self ,id , name = none, maximalKraft = none, alter = none, anzahlPfoten = none):
        self.id = id
        self.name = name
        self.maximalKraft = maximalKraft 
        self.alter = alter 
    	self.anzahlPfoten = anzahlPfoten 
    
class Katze(Lebewesen):
    __mapper_args__ = {'polymorphic_identity':'Katze'}
    
class LanghaarKatze(Katze):
    __mapper_args__ = {'polymorphic_identity':'LanghaarKatze'}

    haarlaenge= Column(Integer)
    hight = Column(Integer)
    
    #Konstruktor
    def __init__(self ,id , name = none, maximalKraft = none, alter = none, haarlaenge = none, hight  = none  ):
        self.id = id
        self.name = name
        self.maximalKraft = maximalKraft 
        self.alter = alter 
        self.haarlaenge = haarlaenge 
        self.hight  = hight  


#Warum brauch ich das hier nochmal, kommt das nicht von base ? 
engine = create_engine('postgresql://postgres:passwort1234@localhost:5432/test', echo=False)
Session = sessionmaker(bind=engine)
sess = Session()

#Auch hier sind die Inputs default auch none, weil ich hoffte dass es das Problem löst
def add_entry(Klasse, id , name = none, maximalKraft = none, alter = none, anzahlPfoten = none, haarlaenge = none, hight  = none):
    obj = Klasse( id , name , maximalKraft , alter , anzahlPfoten , haarlaenge , hight )
    sess.add(obj)
    sess.commit()
    sess.close()
Beim austesten:

Code: Alles auswählen

#Dieser Aufruf funktioniert nicht, da zuviele Argumente übergeben wurden: Fehler: __init__() takes from 1 to 6 positional arguments but 7 were given
add_entry(LanghaarKatze, 1, 'Fluff', 5, 12, 3, 20)

#Dieser Aufruf nicht funktioniert, da zuviele Argumente übergeben wurden: Fehler: __init__() takes from 1 to 5 positional arguments but 7 were given
add_entry(Labrador, 2, 'Bello', 15, 3, 4)

Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@TobiM: In dem Modul wo die `Base` definiert wird sollte `engine` nicht auf Modulebene definiert werden. Das importieren eines Moduls sollte keine Seiteneffekte haben, schon gar nicht das eine Datenbankverbindung geöffnet wird. Ich verstehe auch nicht warum Du das in dem anderen Modul noch mal machst. Das gibt es auch in `base`, da hättest Du das also auch her holen können wie Du das mit `Base` ja auch machst. Aber wie gesagt, das sollte nirgends einfach durch das reine importieren des Moduls passieren.

Die `Base`-Klasse sorgt dafür, dass all die davon abgeleiteten Klassen die ”Magie” besitzen durch Klassenattribute so etwas wie ”Deklarationen” zu erlauben.

Das Schliessen der Sitzung gehört sicher nicht in die `add_entry()`-Methode. Und ich frage immer noch warum Du das Objekt auf so eigenartige Weise *in* der Funktion erzeugen musst/willst, und das nicht einfach *vorher* machst. Du hast alle Informationen.

Die Funktion sollte dann so aussehen:

Code: Alles auswählen

def add_entry(session, obj):
    session.add(obj)
    session.commit()
Und die aufrufe dann so:

Code: Alles auswählen

    add_entry(session, LanghaarKatze(1, "Fluff", 5, 12, 3, 20))
    add_entry(session, Labrador(2, "Bello", 15, 3, 4))
Einfach, lesbar, verständlich, keine Magie nötig.

Anmerkungen: Du beziehst Dich in dem Modul auf `none`, das sollte wohl jedes mal `None` heissen.

`__init__()` ist kein Konstruktor sondern eine Initialisierung. Der Konstruktor heisst in Python `__new__()` und wird nur sehr selten verwendet. An der Stelle ist dann eigentlich immer etwas ”magisches” wenn man von der normalen Objekterstellung abweichen will.

Ich sehe auch den Sinn nicht wirklich, denn `Base` sorgt schon für eine `__init__()`. Ja, da muss man dann die Argumentnamen angeben, aber der Lesbarkeit schadet das ja nicht wenn man auch beim erstellen des Objekts weiss was 5, 12, 3, 20 bei einer Langhaarkatze eigentlich bedeuten sollen.

Zudem ist das eher ungewöhnlich die ID anzugeben, denn genau die ist üblicherweise `None` und wird von der Datenbank vergeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
TobiM
User
Beiträge: 15
Registriert: Mittwoch 10. März 2021, 09:06

@ __blackjack__ vielen Dank, das hat mir sehr geholfen. Ich werde nun einiges umbauen und hoffe dass danach alles so funktioniert.
Antworten