Seite 1 von 2

Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 18:08
von YAPD
Hallo Zusammen,

ich beschäftige mich gerade mit Klassen und habe in dem Zusammenhang eine
Frage an Euch Pros, die die Initialisierung der Klasse betrifft.

Initialisiert man mit __new__( ) nur die neue Klasse und gibt sie zurück, wie hier :

Code I :

Code: Alles auswählen

class customers( )

    example_list = [100, 200]

    def __new__(cls):
        print("Creating Instance !")

        instance = super(customers, cls).__new__(cls)

        print("Instance : {}".format(instance))
        print("Custom : {}".format( object.__new__(cls) ) )

        return object.__new__(cls)
Und was ist der Vorteil / Nachteil, wenn ich

Code: Alles auswählen

object.__new__(cls)

anstatt

Code: Alles auswählen

super(Customers, cls).__new__(cls)
benutze.


Ist es außerdem ratsam, die New( ) Methode für andere
Zwecke zu nutzen ?

Zum Beispiel ein Modul, das mir mit folgendem Code
die verfügbaren Sprachen anzeigen soll :

Code II :

Code: Alles auswählen

import CSV_VT
CSV_VT.available_languages( properties = False )
Dazu die Klasse :

Code: Alles auswählen

class available_languages:
    def __new__(self, properties=False):

        self.show_properties = properties
        results = available_languages.get(self)
        return results
Und wenn ich in Code I noch __repr__ hinzufüge, gibt er anstatt das Objekt
die Liste aus :

Code: Alles auswählen

     def __repr__( Self ) :
         return Self.examplelist.__str__( )
Ich weiß dass __str__( ) es zu einem String konvertiert, da sonst
__repr__ einen Fehler wirft. Aber wann called er es, wenn ich es
mit

Code: Alles auswählen

customer1 = customers( )
aufrufe ?

Code: Alles auswählen

Output ohne __repr__ : <__main__.Customers object at 0x000001E57636CE20>
Output mit __repr__ : [100, 200]
Grundsätzlich geht es mir darum, wie man Klassen am Besten und effektivsten
gestaltet, wenn man eine Anwendung entwirft.

Vielen Dank im Voraus

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 18:17
von __deets__
__new__ ist Teil der Meta-Magie von Python, und das ist ein sehr fortgeschrittenes Thema, das man selten braucht. Und ich behaupte mal du im Moment zumindest gar nicht.

Die Frage zu __repr__ ist zu konfus. Aber auch da sollte man einen String zurueckgeben, und nicht einfach ein Objekt. Aber wenn man das tut, dann ist es auch das, was da eben angezeigt wird. Was sonst sollte da angezeigt werden?

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 18:25
von YAPD
Naja, erstmal solltest du, mit Verlaub, nicht entscheiden, was ich lernen soll, bzw. mit was ich mich beschäftige.
Und bei meinem Learning bin ich mittlerweile halt bei Klassen angekommen, daher versuche ich es zu verstehen.
Gerade das Beispiel mit "available_languages" hat mir gezeigt, dass es viele Varianten gibt, wie man Klassen
gestalten kann. Daher habe ich hier auf Tipps von den Experten gehofft.

Also nicht böse gemeint, aber ich würde trotzdem gerne dahintersteigen, gerade wozu man __new__ genau
braucht, wenn man mit __init__ das Modul auch erstellt.

Code: Alles auswählen

class customers:

    examplelist= [100, 200]

    def __new__(cls):
        print("Creating Instance !")

        instance = super(customers, cls).__new__(cls)

        print("Instance : {}".format(instance))
        print("Custom   : {}".format( object.__new__(cls)))

        return object.__new__(cls)

    def __init__(self):
        print("Initializing Instance !")
Denn wenn ich hier new( ) komplett herausnehme, erhalte ich trotzdem das Objekt. Daher
wird es wohl für so Beispiele wie "available_languages" sein, wenn man den Wert direkt
ohne weitere Befehle erhalten will. :)

Dann gibt es noch Beispiele wie sowas :

Code: Alles auswählen

class AbstractClass(object):

    def __new__(cls, a, b):
        instance = super(AbstractClass, cls).__new__(cls)
        instance.__init__(a, b)
        return 3

    def __init__(self, a, b):
        print "Initializing Instance", a, b
Also die Init( ) Funktion direkt über new( ) aufrufen.

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 18:40
von Sirius3
@YAPD: an Deinem Code ist so viel falsch. Es fängt schon mit der Schreibweise von Modulen und Klassen an. Module schreibt man wie Variablen und Funktionen komplett klein, also csv_vt, wobei man auch bei Modulen keine kryptischen Abkürzungen benutzen sollte.
Klassen schreibt man dagegen mit großen Anfangsbuchstaben, so dass man auch gleich erkennen kann, was eine Klasse ist, also AvailableLanguages oder Customers, so kann man auch gleich eine passende Instanz customers nennen, ohne in Konflikte zu laufen.
In available_languages.__new__ benutzt Du `self` statt `cls`, was verwirrend ist, weil das erste Argument von __new__ immer die Klasse ist. In __repr__ ist dann self fälschlicherweise gross geschrieben. Magische Funktionen ruft man eigentlich nicht direkt auf, eine Liste wandelt man mit str(self. examplelist) in einen String um.
__repr__ wird dann aufgerufen, wenn die Repräsentation eines Objekts gebraucht wird.

Du fragst, wann man beim Klassendesign beim Entwurf einer Anwendung __new__ benutzt, und die Antwort ist, eigentlich nie, wenn man es vermeiden kann.

Zur Frage nach `super` gilt das selbe, wie bei jeder anderen Methode auch. `super` braucht man nur bei komplexen Mehrfachvererbungen, und dann ist es quasi unmöglich `super` sauber zu benutzen, also auch hier gilt, dass man das eigentlich nie braucht, außer die Klasse, von der man erbt benutzt schon `super`.

Die Klasse `available_languages` verstehe ich überhaupt nicht, weil sie so keinen Sinn macht. Dazu mußt Du schon vollständigeren Code zeigen.

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 19:02
von YAPD
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 18:40 @YAPD: an Deinem Code ist so viel falsch. Es fängt schon mit der Schreibweise von Modulen und Klassen an. Module schreibt man wie Variablen und Funktionen komplett klein, also csv_vt, wobei man auch bei Modulen keine kryptischen Abkürzungen benutzen sollte.
Klassen schreibt man dagegen mit großen Anfangsbuchstaben, so dass man auch gleich erkennen kann, was eine Klasse ist, also AvailableLanguages oder Customers, so kann man auch gleich eine passende Instanz customers nennen, ohne in Konflikte zu laufen.
Danke für den Hinweis mit der Schreibweise. Ist in jedem Post immer wieder eine Bereicherung :)
Was außer dass ich CSV_VT einmal groß geschrieben habe, war denn noch falsch ? Nichts, denke
ich, da ich extra "black" drüber laufen gelassen habe. Aber Recht hast du ja. Wenn mans trotzdem
immer wieder macht, muss man sich die Bemerkungen auch gefallen lassen :)
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 18:40 In available_languages.__new__ benutzt Du `self` statt `cls`, was verwirrend ist, weil das erste Argument von __new__ immer die Klasse ist. In __repr__ ist dann self fälschlicherweise gross geschrieben. Magische Funktionen ruft man eigentlich nicht direkt auf, eine Liste
wandelt man mit str(self. examplelist) in einen String um. __repr__ wird dann aufgerufen, wenn die Repräsentation eines Objekts gebraucht wird.
Die Art, wie die new() Methode geschrieben ist, habe ich von
https://dev.to/pila/constructors-in-pyt ... s-new-2f9j

Genauer von Beispiel 2.
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 18:40 Die Klasse `available_languages` verstehe ich überhaupt nicht, weil sie so keinen Sinn macht. Dazu mußt Du schon vollständigeren Code zeigen.
Zu der Klasse "Available_Languages" hier der ganze Code :

Code: Alles auswählen

class Available_Languages:
    def __new__(self, properties=False):

        self.show_properties = properties
        results = Available_Languages.get(self)
        return results

    def get(self):

        standard_languages = Languages()
        self.available_languages = []

        for language in standard_languages.csv_languages_standards:

            if self.show_properties is True:
                parameters = standard_languages.csv_languages_standards[language]
                print(
                    f'{language:>10s} | {Parameters["Delimiter"]:<2s}| {Parameters["Quote_Character"]:<0s} | {Parameters["Quoting"]:<3s}'
                )

            self.available_languages.append(language)

        return self.available_languages

class Languages( ) :

    csv_languages_standards = {
        "Standard": {
            "Delimiter": ",",
            "Quote_Character": '"',
            "Quoting": "QUOTE_MINIMAL",
        },
        "Unix": {"Delimiter": ",", "Quote_Character": '"', "Quoting": "QUOTE_NONE"},
        "XLS": {"Delimiter": ",", "Quote_Character": '"', "Quoting": "QUOTE_ALL"},
    }  
                                
Anschließend kann ich mit

Code: Alles auswählen

Langs = Available_Languages( )
print( Langs )
die verfügbaren Sprachen anzeigen lassen. Das geht nur ( imho ), weil ich die new( )Methode benutze um die Werte
zurückzu geben. Denn __init__ erlaubt ja bekanntlich nur 'None' .

Ich hoffe, damit wird es für dich klarer. Sorry, wenn es missverständlich war.

EDIT : Moment. Kann ich hier nicht __repr__ nehmen ?

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 19:30
von __deets__
Ich habe nichts entschieden für dich. Ich habe dir basierend auf meiner Erfahrung von mehreren Jahrzehnten Python den Hinweis gegeben, das es sich bei __new__ um ein extrem randständiges Thema handelt, um das du dich nicht kümmern musst, weil es in deiner Programmierpraxis keinerlei Rolle spielen wird. Und damit deine Energie in die Vertiefung von den vielen anderen Themen stecken kannst, die du auch noch nicht drauf hast. Selbstverständlich darfst du das ignorieren. So wie Namenskonventionen zb.

Dein Available_Languages ist einfach nur ein komplizierter Weg, eine simple Funktion zu schreiben, die eine Liste zurück gibt. Warum machst du das?

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 19:35
von Sirius3
In dem von Dir verlinkten Artikel wird nirgends `self` benutzt, also kannst Du das nicht davon haben.
Ebenso ist das `self` von `get` falsch, da es sich hier offensichtlich um eine Klassenmethode handelt, die aber nicht so geschrieben wurde.
Mit `show_properties` benutzt Du eine globale Klassenvariable, die man ebensowenig benutzen sollte, genausowenig wie sonstige globale Variablen. Warum übergibst Du das nicht als Argument an `get´?
True vergleicht man nicht mit `is`. `Parameters` ist im Formatstring falsch geschrieben.

Code: Alles auswählen

class AvailableLanguages:
    def __new__(cls, show_properties=False):
        return cls.get(show_properties)

    @classmethod
    def get(cls, show_properties=False):
        standard_languages = Languages()
        cls.available_languages = []
        for language in standard_languages.csv_languages_standards:
            if show_properties:
                parameters = standard_languages.csv_languages_standards[language]
                print(
                    f'{language:>10s} | {parameters["Delimiter"]:<2s}| {parameters["Quote_Character"]:<0s} | {parameters["Quoting"]:<3s}'
                )
            cls.available_languages.append(language)
        return cls.available_languages
`get` ist eigentlich überflüssig, weil __new__ nur aus dessen Aufruf besteht.
Die for-Schleife ist eigentlich überflüssig, außer man will wirklich diese Ausgabe.
Bleibt also

Code: Alles auswählen

class AvailableLanguages:
    def __new__(cls, show_properties=False):
        standard_languages = Languages().csv_languages_standards        
        if show_properties:
            for language, parameters in standard_languages.items():
                print(
                    f'{language:>10s} | {parameters["Delimiter"]:<2s}| {parameters["Quote_Character"]:<0s} | {parameters["Quoting"]:<3s}'
                )
        return list(standard_languages)
`_new__` liefert also die Schlüssel eines Wörterbuchs als Liste zurück. Aber warum sollte man eine Liste bekommen, wenn man eigentlich eine Instanz der Klasse `AvailableLanguages` will?
Das ist verwirrend, und kein Anwendungsfall für __new__ und auch kein Anwendugsfall für eine Klasse. Ebensowenig ist `Languages` eine wirkliche Klasse.
In Wirklichkeit sollte der Code daher so aussehen:

Code: Alles auswählen

CSV_LANGUAGE_STANDARDS = {
    "Standard": {
        "Delimiter": ",",
        "Quote_Character": '"',
        "Quoting": "QUOTE_MINIMAL",
    },
    "Unix": {"Delimiter": ",", "Quote_Character": '"', "Quoting": "QUOTE_NONE"},
    "XLS": {"Delimiter": ",", "Quote_Character": '"', "Quoting": "QUOTE_ALL"},
}

def get_available_languages(show_properties=False):
    if show_properties:
        for language, parameters in CSV_LANGUAGE_STANDARDS.items():
            print(
                f'{language:>10s} | {parameters["Delimiter"]:<2s}| {parameters["Quote_Character"]:<0s} | {parameters["Quoting"]:<3s}'
            )
    return list(CSV_LANGUAGE_STANDARDS)

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 20:41
von YAPD
Vielen Dank für deine Antwort Sirius :)
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 19:35 In dem von Dir verlinkten Artikel wird nirgends `self` benutzt, also kannst Du das nicht davon haben.
Ja das stimmt, sorry :ugeek:
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 19:35 Mit `show_properties` benutzt Du eine globale Klassenvariable, die man ebensowenig benutzen sollte, genausowenig wie sonstige globale Variablen. Warum übergibst Du das nicht als Argument an `get´?
OK, danke, das war mir so nicht bewusst. Da der Parameter 'show_properties" nur in der Klasse übergeben wird,
dachte ich, dass er nur dort gilt und nicht global gilt.
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 19:35 Ebenso ist das `self` von `get` falsch, da es sich hier offensichtlich um eine Klassenmethode handelt, die aber nicht so geschrieben wurde.
True vergleicht man nicht mit `is`. `Parameters` ist im Formatstring falsch geschrieben.
Ja das stimmt, das sind Flüchtigkeitsfehler, die einem nicht unterlaufen sollten.
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 19:35 `get` ist eigentlich überflüssig, weil __new__ nur aus dessen Aufruf besteht.
Die for-Schleife ist eigentlich überflüssig, außer man will wirklich diese Ausgabe.
Bleibt also

Code: Alles auswählen

class AvailableLanguages:
    def __new__(cls, show_properties=False):
        standard_languages = Languages().csv_languages_standards        
        if show_properties:
            for language, parameters in standard_languages.items():
                print(
                    f'{language:>10s} | {parameters["Delimiter"]:<2s}| {parameters["Quote_Character"]:<0s} | {parameters["Quoting"]:<3s}'
                )
        return list(standard_languages)
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 19:35 `_new__` liefert also die Schlüssel eines Wörterbuchs als Liste zurück. Aber warum sollte man eine Liste bekommen, wenn man eigentlich eine Instanz der Klasse `AvailableLanguages` will?
Das ist verwirrend, und kein Anwendungsfall für __new__ und auch kein Anwendugsfall für eine Klasse. Ebensowenig ist `Languages` eine wirkliche Klasse.
Hmm, man soll mit dem Befehl = csv_vt.AvailableLanguages( ) eine Liste aller verfügbaren Formatierungen erhalten,
die man dann weiter verarbeiten kann. Wenn es anders geht, bin ich für Vorschläge offen.

Hier nochmal alles in Einem, mit Änderungen von Sirius :

Code: Alles auswählen


class Languages:

    csv_languages_standards = {
        "Standard": {
            "delimiter": ",",
            "quote_character": '"',
            "quoting": "QUOTE_MINIMAL",
        },
        "Unix": {"delimiter": ",", "quote_character": '"', "quoting": "QUOTE_NONE"},
        "XLS": {"delimiter": ",", "quote_character": '"', "quoting": "QUOTE_ALL"},
    }

    def register(self):

        if self.language_parameters["language"] in Languages.csv_languages_standards:
            print("The Specified Name For The Language Is Already Registered !")
            return self

        Languages.csv_languages_standards[self.language_parameters["language"]] = {
            "delimiter": self.language_parameters["delimiter"],
            "quote_character": self.language_parameters["quote_character"],
            "quoting": self.language_parameters["quoting"],
        }

        print(
            "Sucessfully Registered Language : {}".format(
                self.language_parameters["language"]
            )
        )


class RegisterLanguage:
    def __new__(self, language, **parameters):

        print("Setting Up Parameters ...")

        self.language_parameters = {
            "language": language,
            "delimiter": parameters.get("delimiter", "None"),
            "quote_character": parameters.get("quote_character", "None"),
            "quoting": parameters.get("quoting", "None"),
        }

        for x in self.language_parameters:

            if self.language_parameters[x] == "None":
                print(f"The Parameter For '{x}' Is Missing !")
                return self

        print("Registering Language : {}".format(self.language_parameters["language"]))
        Languages.register(self)


class AvailableLanguages:
    def __new__(cls, show_properties=False):
        standard_languages = Languages().csv_languages_standards
        if show_properties:
            for language, parameters in standard_languages.items():
                print(
                    f'{language:>10s} | {parameters["delimiter"]:<2s}| {parameters["quote_character"]:<0s} | {parameters["quoting"]:<3s}'
                )
        return list(standard_languages)


langs1 = AvailableLanguages()                                                             #  -> Zeigt alle verfügbaren Formatierungen aus 'csv_languages_standards' an
print(langs1)                                                                            
RegisterLanguage("Deutsch", delimiter=",", quoting="QUOTE_MINIMAL", quote_character='"')  #  -> Fügt der Klasse 'Language' eine neue Formatierung hinzu

langs2 = AvailableLanguages(show_properties=True)
print(langs2)

# Remove_Language( language )                                                              #  -> Entfernt eine bestimmte Formatierung aus Klasse 'Languages'

Ich hoffe, so ist der Code verständlicher.

Der Sinn & Zweck ist eine Formatierung zu hinterlegen, die man variabel anlegen und löschen
und später in der Anwendung verwenden kann.

Kleine Anmerkung : Ich musste mich bei meinen Tests ja nach irgendetwas richten, ich habe in diesem
Fall das Modul "csv" genommen. Wenn ihr Euch das anschaut, benutzt "Dialect" ähnliche Mechanismen :D :)

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 20:45
von sparrow
Wie die pythonische Lösung aussieht, hat dir Sirius3 doch schon gezeigt. Es braucht keine Klassen. Und das verzweifelt da hinein zu prügeln, mit irgendwelchen Konstrukten, die völlig an der Praxis vorbei gehen, ist ein bisschen seltsam.

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 20:51
von YAPD
sparrow hat geschrieben: Donnerstag 12. August 2021, 20:45 Wie die pythonische Lösung aussieht, hat dir Sirius3 doch schon gezeigt. Es braucht keine Klassen. Und das verzweifelt da hinein zu prügeln, mit irgendwelchen Konstrukten, die völlig an der Praxis vorbei gehen, ist ein bisschen seltsam.
Hi Sparrow, danke für deine Antwort, sie hatte sich gerade mit meiner überschnitten. :)

Wie ich in meinem vorherign Post schrieb, musste ich mich bei meinen Tests ja nach irgendetwas richten, ich habe in diesem
Fall das Modul "csv" genommen. Wenn ihr Euch das anschaut, benutzt "Dialect" ähnliche Mechanismen :D :)
Insofern will es nicht reinprügeln, sondern nur praktisch nachstellen.

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 20:56
von YAPD
Ich wollte mir die Bibliothek von 'csv' anschauen, aber finde die "_csv" nicht ???
Wo liegt die ?

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 20:58
von __deets__
Hier: https://github.com/python/cpython/blob/ ... les/_csv.c

Und wo bitte macht Dialect etwas mit __new__?

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 21:09
von YAPD
__deets__ hat geschrieben: Donnerstag 12. August 2021, 20:58 Hier: https://github.com/python/cpython/blob/ ... les/_csv.c

Und wo bitte macht Dialect etwas mit __new__?
Das hatte sich eher auf das ganze Vorgehen bezogen, als auf die __new__Methode, aber wenn man sich die
Datei anschaut sind es alles nur Funktionen, die aufgerufen werden.

Aber noch was : Wo liegt die _csv jetzt denn letztendlich, ich wusste nicht, dass man
so versteckte Files einbinden kann.

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 21:13
von __deets__
Das ist nicht versteckt, sondern in C. Unter Windows steckt das einfach in der Python DLL. Unter Unixen ist es ein Shared object file, und wird beim Import einfach geladen mit dlopen, und dann als Extension registriert es seine diversen Objekte etc.

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 21:16
von sparrow
@YAPD: Aber das ganze Vorgehen ist doch ohne __new__ umgesetzt in dem genannten Modul? Überhaupt führt ein grep nach __new__ in der Standard-Bibliothek zu einer sehr überschaubaren Anzahl von Treffern. __init__ scheint hingegen in jeder Klasse benutzt zu werden. Ob das einen Grund hat?

Und deine Klassen haben nach wie vor keine Not überhaupt Klassen zu sein. Du versuchst da Techniken anzuwenden, die nicht angebracht sind. Wonach auch immer du lernst, du solltest das in meinen Augen in Frage stellen.

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 21:37
von YAPD
sparrow hat geschrieben: Donnerstag 12. August 2021, 21:16 @YAPD: Aber das ganze Vorgehen ist doch ohne __new__ umgesetzt in dem genannten Modul? Überhaupt führt ein grep nach __new__ in der Standard-Bibliothek zu einer sehr überschaubaren Anzahl von Treffern. __init__ scheint hingegen in jeder Klasse benutzt zu werden. Ob das einen Grund hat?
Ja das ist mir bewusst, es hat mich halt nur die Funktionsweise interessiert. :)
sparrow hat geschrieben: Donnerstag 12. August 2021, 21:16 Und deine Klassen haben nach wie vor keine Not überhaupt Klassen zu sein. Du versuchst da Techniken anzuwenden, die nicht angebracht sind. Wonach auch immer du lernst, du solltest das in meinen Augen in Frage stellen.
Danke für den Hinweis Sparrow. Auch wenn man es mit einer Lösung XY vielleicht so hinkriegt, wie man sich das vorstellt,
ist das trotzdem nicht immer die beste Variante. Wie hier, wo so viele Klassen unangebracht sind. Dann lieber wirklich die
eine Datei importieren und die jeweiligen Funktionen aufrufen ;) :)

VG
YAPD

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 21:39
von Sirius3
Nochmal zu Deinem Code mit `RegisterLanguage`: Du beschäftigst Dich hier mit Dingen, die weit über Deinen aktuellen Kenntnisstand hinausgehen. Du kannst Klassen noch nicht richtig anwenden, und solange Du das noch nicht kannst, ist __new__ etwas, vom dem Du die Finger lassen solltest.
Die Klasse `Languages` hat kein Attribut language_parameters, also kannst Du das auch nicht benutzen. Dann greifst Du auf Languages.csv_languages_standards über den Klassennamen, statt über self zu, was auch ein Zeichen dafür ist, dass Du einen Fehler hast.
Bei einer `register`-Methode erwartet jeder, dass da etwas übergeben wird, was registriert werden soll, das ist bei Dir aber wieder so eine komische globale Variable.
`RegisterLanguage.__new__` gibt jetzt sogar None zurück. Das sollte sogar Dir klar sein, dass das nichts sinnvolles ist. Dann hast Du wieder ein `self`, das eigentlich ein `cls` sein sollte, das Du dann aber als ersten Parameter einer Methode Languages.register in einer ganz anderen Klasse übergibst.
Und schließlich, wie Du RegisterLanguage benutzt, nämlich, dass Du mit dem Rückgabewert gar nichts machst, ist ein weiteres Zeichen, dass Du keine Klasse hast, sondern eine einfache Funktion, die Du nur unendlich kompliziert geschrieben hast.
Der String "None" ist etwas anders als None.

Ich würde sogar sagen, dass Klassen für Dich generell noch eine Nummer zu kompliziert sind, und Du erst lernen mußt, was Funktionen sind, und wie man sie benutzt. Du willst zu schnell zu viel, beschäftige Dich mit einfacheren Dingen.

Re: Klassen : __new__( ) & __init__( )

Verfasst: Donnerstag 12. August 2021, 22:58
von YAPD
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 21:39 Nochmal zu Deinem Code mit `RegisterLanguage`: Du beschäftigst Dich hier mit Dingen, die weit über Deinen aktuellen Kenntnisstand hinausgehen. Du kannst Klassen noch nicht richtig anwenden, und solange Du das noch nicht kannst, ist __new__ etwas, vom dem Du die Finger lassen solltest.

Die Klasse `Languages` hat kein Attribut language_parameters, also kannst Du das auch nicht benutzen. Dann greifst Du auf Languages.csv_languages_standards über den Klassennamen, statt über self zu, was auch ein Zeichen dafür ist, dass Du einen Fehler hast.
Bei einer `register`-Methode erwartet jeder, dass da etwas übergeben wird, was registriert werden soll, das ist bei Dir aber wieder so eine komische globale Variable.
Was meinst du ? Das Attribut "self.language_parameters kommt doch von "RegisterLanguage" ( Aufruf über : Languages.register(self) )
Oder hab ich da was übersehen ?
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 21:39 `RegisterLanguage.__new__` gibt jetzt sogar None zurück. Das sollte sogar Dir klar sein, dass das nichts sinnvolles ist. Dann hast Du wieder ein `self`, das eigentlich ein `cls` sein sollte, das Du dann aber als ersten Parameter einer Methode Languages.register in einer ganz anderen Klasse übergibst.
Und schließlich, wie Du RegisterLanguage benutzt, nämlich, dass Du mit dem Rückgabewert gar nichts machst, ist ein weiteres Zeichen, dass Du keine Klasse hast, sondern eine einfache Funktion, die Du nur unendlich kompliziert geschrieben hast.
Der String "None" ist etwas anders als None.
Ja. RegisterLanguage ist hier nur dazu da, um register( ) in Language aufzurufen. Das meintet ihr ja vorher mit überflüssige Klassen. :(
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 21:39 Ich würde sogar sagen, dass Klassen für Dich generell noch eine Nummer zu kompliziert sind, und Du erst lernen mußt, was Funktionen sind, und wie man sie benutzt. Du willst zu schnell zu viel, beschäftige Dich mit einfacheren Dingen.
:o :| :cry:

Re: Klassen : __new__( ) & __init__( )

Verfasst: Freitag 13. August 2021, 07:14
von Sirius3
Die Klasse `Languages` hat nichts mit der Klasse `RegisterLanguage` zu tun. Du benutzt die Klasse `Language` als Lagerraum für Funktionen, die Du an einer ganz anderen Stelle aufrufst mit Objekten, die nicht vom Typ Language sind.
Was Du Dir ganz einfach merken kannst ist, dass eine Klasse, die keinen Zustand hat, keine Klasse ist. Dass eine Methode niemals über Klassenname.methodenname aufgerufen wird (außer man will explizit die Methode einer Elternklasse aufrufen), dass `self` immer vom Typ der Klasse ist, in dem die Methode definiert ist.
Wenn Du dich nicht an diese Regeln hältst, dann hast Du einen Programmierfehler. Dass das Python3 da keine Fehlermeldung wirft, heißt nicht, dass es richtig ist.
Du tust Dir selbst einen Gefallen, wenn Du langsamer vorgehst, und erst Funktionen richtig gut beherrschst, und dann nochmal frisch mit Klassen beginnst, und zwar so, wie sie gedacht sind.

Re: Klassen : __new__( ) & __init__( )

Verfasst: Freitag 13. August 2021, 15:01
von YAPD
Ok Gut. Dann gib mir doch mal ne Quelle, wo man das so lernen kann, wie du dir das vorstellst.
Anscheinend sind alle Beispiele, die ich aufführe, Beispiele, wie man es nicht machen soll.
Ich weiß, wie man Funktionen schreibt, also die Standards, wie das Grundgerüst aussieht.
die Übergabe von Variablen etc. . Was muss man denn noch wissen, um es "richtig gut"
zu beherrschen ?


Was hältst du denn z.B. von diesem Code :

Code: Alles auswählen

class excel(Dialect):
    """Describe the usual properties of Excel-generated CSV files."""
    delimiter = ','
    quotechar = '"'
    doublequote = True
    skipinitialspace = False
    lineterminator = '\r\n'
    quoting = QUOTE_MINIMAL
register_dialect("excel", excel)