Seite 2 von 2
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 15:22
von __deets__
Wurde doch angemerkt. Ein Argument erstmal an self zu binden, um es dann in get() zu benutzen, statt es eben als Parameter zu übergeben. Das ist jetzt eher nicht gewusst wie es geht.
Und gerade Sirius3 und __blackjack__ liefern hier auch eine Menge Code. Den kann man sich auch anschauen.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 15:27
von YAPD
__deets__ hat geschrieben: Freitag 13. August 2021, 15:22
Und gerade Sirius3 und __blackjack__ liefern hier auch eine Menge Code. Den kann man sich auch anschauen.
Sorry, das muss ich übersehen haben. In welchem Beitrag in diesem Thread ist
die Menge an Code versteckt ? Ich sehe es nicht.
Ich weiß, dass das Grundgerüst einer Klasse so aussieht :
Code: Alles auswählen
class example1():
standard_language = "english"
def __init__(self, parameter) :
self.parameter = parameter
self.standard_languages = []
def execute(self) :
print("Executing {}".format( self.parameter))
test = example1("Testumgebung")
test.execute()
Dabei ist "standard_language" eine Variable, die von allen Instanzen verwendet wird,
wogegen "self.parameter und "self.standard_languages" nur für die jeweilige Instanz
gelten.
Man initialisiert erst die Instanz, hier Testumgebung :
und führt anschließend ggf. eine anderen Funktion aus :
Bei der Variablenübergabe kann man die einzelnen Parameter übergeben :
Code: Alles auswählen
def __init__(self, name , language):
...
Aufruf : Klasse("Max" , "German)
oder die Parameter, ich nenne es mal anonymisieren. Somit kann man mit
einzelne Werte übergeben, die
aber nicht zwingend vorhanden sein müssen.
Mit
erreicht man das selbe, nur mit
Dicts, also ist hier der Aufruf :
Soweit richtig ??
VG
YAPD
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 15:41
von __deets__
Erstens hat Sirius3 deinen Code umgeschrieben. Und zweitens habe ich nicht gemeint, dass nun dieser Thread vollgestopft mit Code wäre. Sondern versucht deine Frage zu beantworten, wo denn Beispiele wären, wie man es richtig macht. Und das sind eben korrigierte oder komplett selbst geschriebene Beispiele von den beiden (und anderen) hier im Forum.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 16:14
von __deets__
Diverse Anmerkungen zu deinem Beispiel:
- auch wenn es dir auf die Eier geht, man haelt sich an bestimmte Konventionen, und dazu gehoert, dass Klassen SoGeschriebenWerden, also CamelCase, und Funktionen und Parameter klein. Ja, auch die Standardbibliothek hat Gegenbeispiele, aber Ausnahmen bestaetigen die Regel, yaddayadda... Also ist example1 schon mal doppelt doof: Es sollte Example heissen. Und warum ist da eine 1 dran?
- das ist keine andere Funktion, das nennt man Methode. Und Methoden fuehrt man nicht "ggf." aus. Eine Klasse ohne weitere Methoden kann man auch gleich als Funktion(!) schreiben. Denn sonst gibt's keinen Grund, ein Objekt aufzuheben, wenn man damit nie wieder etwas macht.
- das ist nicht anonymisiert, sondern einfach ein Weg, positionale Argumente via einer Sequenz anzugeben. Was auch nichts mit Klassen per se zu tun hat, sondern immer bei allem was aufrufbar ist, funktioniert. Und es stimmt auch nicht, was du behauptest, das man damit Argumente "einsparen" koennte. Positionale Argumente wie von dir gezeigte muessen IMMER vollstaendig angegeben werden. Man kann stattdessen Schuesselwort-Argumente mit einem default-Wert. *Die* kann man auch weglassen beim Aufruf, dafuer ist ja der default-Wert da.
- dein zweites Beispiel scheint Schluesselwort-Argumente benutzen zu wollen, ist aber falsch, weil dazu muss man ** benutzen.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 16:18
von YAPD
Thema bitte schließen
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 16:22
von __deets__
YAPD hat geschrieben: Freitag 13. August 2021, 16:18
Thema bitte schließen
Diese Funktion gibt es hier nicht.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 16:35
von YAPD
__deets__ hat geschrieben: Freitag 13. August 2021, 16:22
YAPD hat geschrieben: Freitag 13. August 2021, 16:18
Thema bitte schließen
Diese Funktion gibt es hier nicht.
Es geht schon, wird aber wahrscheinlich nur in Ausnahmefällen gemacht
wie hier :
https://www.python-forum.de/viewtopic.php?f=1&t=52699
Dann bitte als erledigt markieren.
Danke !
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 16:39
von __deets__
Das ist etwas anderes. Das ist nicht "erledigt", das ist geschlossen, und der Grund dafuer ist, dass der User rausgeworfen wurde, und da keine Diskussion mehr stattfinden sollte. Mit anderen Worten: da musste moderierend eingegriffen werden.
Hier muss nicht moderierend eingegriffen werden. Sondern du moechtest augenscheinlich nur mit dem Fuss aufstampfen. Das ist auch allen Beteiligten ohne einen geschlossenen Thread klar.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 16:47
von YAPD
__deets__ hat geschrieben: Freitag 13. August 2021, 16:14
Diverse Anmerkungen zu deinem Beispiel:
- auch wenn es dir auf die Eier geht, man haelt sich an bestimmte Konventionen, und dazu gehoert, dass Klassen SoGeschriebenWerden, also CamelCase, und Funktionen und Parameter klein. Ja, auch die Standardbibliothek hat Gegenbeispiele, aber Ausnahmen bestaetigen die Regel, yaddayadda... Also ist example1 schon mal doppelt doof: Es sollte Example heissen. Und warum ist da eine 1 dran?
- das ist keine andere Funktion, das nennt man Methode. Und Methoden fuehrt man nicht "ggf." aus. Eine Klasse ohne weitere Methoden kann man auch gleich als Funktion(!) schreiben. Denn sonst gibt's keinen Grund, ein Objekt aufzuheben, wenn man damit nie wieder etwas macht.
- das ist nicht anonymisiert, sondern einfach ein Weg, positionale Argumente via einer Sequenz anzugeben. Was auch nichts mit Klassen per se zu tun hat, sondern immer bei allem was aufrufbar ist, funktioniert. Und es stimmt auch nicht, was du behauptest, das man damit Argumente "einsparen" koennte. Positionale Argumente wie von dir gezeigte muessen IMMER vollstaendig angegeben werden. Man kann stattdessen Schuesselwort-Argumente mit einem default-Wert. *Die* kann man auch weglassen beim Aufruf, dafuer ist ja der default-Wert da.
- dein zweites Beispiel scheint Schluesselwort-Argumente benutzen zu wollen, ist aber falsch, weil dazu muss man ** benutzen.
Ja es geht mir auf die Eier, wenn bei snippets, die nur als Beispiel dienen und nicht wirklich benutzt werden, immer wieder darauf herumgeritten wird,
das muss ich zugeben. Ich halte die Regeln nach den bekannten Style Templates ein und benutze black für die Formatierung ( was manchmal auch
Zeilen trennt, wo es gar nicht sein muss
Zu dem Code :
1. Ich wollte eigentlich noch einen 2. Code posten, daher die 1 hinter example
2. Du hast Recht und ich weiß dass man positionale Argumente ( * , ** ) auch in normale Funktionen verwenden kann
3. Ich habe nie behauptet, dass man so Argumente einsparen kann, ich habe legendlich darauf hingewiesen, dass
so die Variablen nicht gleich eingangs verarbeitet werden, sondern in der Methode zugewiesen werden können.
4. Natürlich müssen positionale Argumente immer vollständig angegeben werden. Bzw. wenn ein Argument
falsch ist, muss es abgefangen werden. Das ist mir bewusst.
5. Das zweite Beispiel sollte wirklich ein ** verwenden, das war ein Flüchtigkeitsfehler, sorry
Nichts für ungut, ich habe halt irgendwie auf eine andere Hilfe gehofft, als mir zuteil wurde und das hat mich
ein bisschen enttäuscht. Außer dass die Formulierung bei mir hakt, ist das doch die Grundstruktur von
Klassen, oder nicht ?
Noch eine Frage zur Funktionsweise :
Code: Alles auswählen
class Example:
standard_language = "english"
standard_dict = {"name": "Max", "language": "German"}
def __init__(self, **parameter):
self.parameter = parameter
self.standard_languages = []
def execute(self, *parameter):
print("Executing {}".format(self.parameter))
Code: Alles auswählen
test.standard_language = "spanish"
test.__delattr__(standard_language)
print(test.standard_language)
Output : NameError: name 'standard_language' is not defined
Code: Alles auswählen
test.standard_language = "spanish"
del test.standard_language
print(test.standard_language)
Output : english
Was ist der genaue Unterschied ? __delatrr__ löscht das ganze Attribut, und del nur
das der Instanz und setzt es wieder auf den Ursprungswert ?
VG
YAPD
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 17:12
von rogerb
@YAPD,
Ja es geht mir auf die Eier, wenn bei snippets, die nur als Beispiel dienen und nicht wirklich benutzt werden, immer wieder darauf herumgeritten wird
Du kannst doch deinen Code so schreiben wie du willst. Du must dich auch nicht dafür rechtfertigen. Das sind nur Anmerkungen. Ob du das beherzigen willst, ist ganz allein deine Sache!
Und da es gerade so gut passt: In deiner Signatur fehlt ein 'p'

Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 17:14
von YAPD
rogerb hat geschrieben: Freitag 13. August 2021, 17:12
@YAPD,
Ja es geht mir auf die Eier, wenn bei snippets, die nur als Beispiel dienen und nicht wirklich benutzt werden, immer wieder darauf herumgeritten wird
Du kannst doch deinen Code so schreiben wie du willst. Du must dich auch nicht dafür rechtfertigen. Das sind nur Anmerkungen. Ob du das beherzigen willst, ist ganz allein deine Sache!
Und da es gerade so gut passt: In deiner Signatur fehlt ein 'p'
Ja du hast Recht. Also wie gesagt, nichts für ungut.
Ich wollte hier keinen vor den Kopf stoßen, wie man
so sagt.

Ja muss das gleich ändern im Profil

Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 18:14
von Sirius3
Ich weiß nicht, ob ich es nicht schon an anderer Stelle erwähnt habe, aber explizit ruft man Methoden mit __xxx___ sehr selten auf. Und wenn, dann muß man es auch richtig machen:
Und das ist äquivalent zu
oder falls man es variabel will:
Von daher ist die erste Variante einfach nur umständlich.
Zweitens, falls ich es nicht schon erwähnt habe, werden alle Attribute in __init__ angelegt, weil damit klar wird, welche Attribute eine Instanz hat. Daraus ergibt sich auch, dass man keine Attribute löscht, von daher sollte ein del in normalem Code nicht vorkommen.
Variablen auf Klassenebene sind gleich zu setzen mit globalen Variablen, und sollten nicht existieren, da sollte es nur Konstanten geben, also Variablen die KOMPLETT GROSS geschrieben werden.
Falls es sich um eine Variable handelt, sollte es so aussehen:
Code: Alles auswählen
class Example:
def __init__(self, **parameter):
self.standard_language = "english"
self.parameter = parameter
self.standard_languages = []
def execute(self, *parameter):
print("Executing {}".format(self.parameter))
test = Example(name="abc")
test.standard_language = "spanish"
Re: Klassen : __new__( ) & __init__( )
Verfasst: Freitag 13. August 2021, 22:09
von __blackjack__
@YAPD: ``del instance.attribute_name`` löscht das Attribut auf dem Objekt. Wenn auf der Klasse ein gleichnamiges Attribut existiert, dann ist das danach über das Objekt erreichbar, nach den ganz normalen Regeln das ”nicht-magische” Namen zuerst auf dem Objekt und dann in der Klassenhierarchie nachgeschlagen werden. ”Magische” Namen (`__???___`) werden immer gleich in der Klassenhierarchie nachgeschlagen, nicht auf dem Objekt.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Samstag 14. August 2021, 17:15
von YAPD
Hallo Zusammen,
ich hoffe, ich nerve Euch nicht damit zu sehr, aber ich hätte nochmal eine
Verständisfrage zu Klassen. Ich habe folgende Bedingungen für diese Übung
festgelegt :
1. Ich importiere das Modul pm
2. Ich kann folgende Befehle ausführen :
- pm.reader()
- pm.list_languages()
- pm.create_language()
- pm.remove_language()
Außerdem gibt es noch eine Klasse "languages()" , die die verfügbaren Sprachen hält.
Dabei soll reader() als Parameter das Objekt der Klasse "languages()" mit allen verfübaren
Sprachen erhalten.
Außerhalb von reader() muss es möglich sein, über 'create_language()' oder 'remove_language()'
Sprachen hinzuzufügen.
Gibt es eine Möglichkeit, keine globale Variable des Typs "available_languages" zu erstellen ?
Ich sehe nämlich keine, wenn ich es in __init__ packe, legt er die Liste ja immer wieder neu an ?
Gemäß der Regel : Nutze NIEMALS globale Variablen
Code: Alles auswählen
# ---------------------------------------------------------------------------------------
class Reader:
def __init__(self):
print("Creating Reader Class !")
languages_class = Languages()
print("Language Class : {}".format(languages_class.available_languages))
# ---------------------------------------------------------------------------------------
class Languages:
available_languages = []
def __init__(self):
print("Languages !")
def register_language(self):
print()
Languages.available_languages.append("TESTUMGEBUNG")
# ---------------------------------------------------------------------------------------
reader_obj = Reader()
Languages().register_language()
VG
YAPD
Re: Klassen : __new__( ) & __init__( )
Verfasst: Samstag 14. August 2021, 18:02
von Sirius3
Funktionen, um etwas global zu registrieren, brauchen zwangsläufig globale Variablen. Alternativ erzeugt man eine lokale Registratur-Instanz, die man den Funktionen als Parameter übergibt, die sie brauchen.
Ein Fehler ist es, ständig neue Language-Instanzen zu erzeugen. Das macht man einmal und legt das als lokale oder globale Variable ab.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Samstag 14. August 2021, 18:08
von rogerb
@YAPD,
Nutze NIEMALS globale Variablen
Es spricht nichts gegen Konstanten auf Modulebene.
Denn es geht ja darum, dass das Verändern von globalen Variablen das problematisch ist.
Wenn man Konstanten komplett groß schreibt, weiß man auch dass man sie nicht ändern soll.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Samstag 14. August 2021, 18:35
von YAPD
Danke für Eure Antworten
Bei so vielen Thread komm ich langsam nicht mehr hinterher
Sirius3 hat geschrieben: Samstag 14. August 2021, 18:02
Ein Fehler ist es, ständig neue Language-Instanzen zu erzeugen. Das macht man einmal und legt das als lokale oder globale Variable ab.
Ja genau das will ich verhindern.
rogerb hat geschrieben: Samstag 14. August 2021, 18:08
Es spricht nichts gegen Konstanten auf Modulebene.
Denn es geht ja darum, dass das Verändern von globalen Variablen das problematisch ist.
Manchmal ist es einfach notwendig, denke ich, gerade bei komplexeren Konstrukten.
rogerb hat geschrieben: Samstag 14. August 2021, 18:08
Wenn man Konstanten komplett groß schreibt, weiß man auch dass man sie nicht ändern soll.
Ist die Schreibeweise in Großbuchstaben Python Standard ?
VG
YAPD
Re: Klassen : __new__( ) & __init__( )
Verfasst: Samstag 14. August 2021, 19:14
von rogerb
Manchmal ist es einfach notwendig, denke ich, gerade bei komplexeren Konstrukten.
Ja durchaus. Für Werte, die man auf Modulebene nur einmal definieren aber mehrmals verwenden will.
Z.B. ein Dateiname zum lesen einer Datei. Wenn ich die mehrmals im Modul lesen will brauche ich sie nur einmal als Konstante definieren.
Falls sich der Dateiname mal ändern sollte brauche ich das dann nur an einer Stelle zu tun.
Ist die Schreibeweise in Großbuchstaben Python Standard ?
Es ist eine Konvention und erleichtert die Zusammenarbeit, weil so alle verstehen, was gemeint ist.
Python ist es aber (fast) egal wie du schreibst.
Python ist eine sehr flexible Sprache bei der zwar vieles möglich, aber nicht alles sinnvoll ist, daher sind Konventionen so wichtig.
Re: Klassen : __new__( ) & __init__( )
Verfasst: Samstag 14. August 2021, 21:19
von sparrow
YAPD hat geschrieben: Samstag 14. August 2021, 18:35Manchmal ist es einfach notwendig, denke ich, gerade bei komplexeren Konstrukten.
Gerade wenn es komplex wirft sind globale Variablen nicht mehr zu warten.