Ich bin ein C ++ Programmierer, der gerade angefangen hat, Python zu lernen. Ich würde gerne wissen, wie Sie Instanzvariablen in großen Python-Klassen verfolgen. Ich bin es gewohnt, eine Datei .h
zu haben, die mir eine ordentliche Liste (mit Kommentaren) aller Mitglieder der Klasse gibt. Aber da Python Ihnen erlaubt, neue Instanzvariablen im laufenden Betrieb hinzuzufügen, wie behalten Sie sie alle im Auge?
Ich stelle mir ein Szenario vor, in dem ich fälschlicherweise eine neue Instanzvariable hinzufüge, obwohl ich bereits eine hatte - aber es waren 1000 Zeilen von meiner Arbeitsstelle entfernt. Gibt es Standardverfahren, um dies zu vermeiden?
Bearbeiten: Es scheint, dass ich etwas Verwirrung mit dem Begriff "Elementvariable" geschaffen habe. Ich meine wirklich Instanzvariable, und ich habe meine Frage entsprechend bearbeitet.
Vor allem: Klassenattribute oder Instanzattribute? Oder beides? =)
Normalerweise fügen Sie einfach Instanzattribute in __init__
und Klassenattribute in die Klassendefinition ein, oft vor Methodendefinitionen ..., die wahrscheinlich 90% der Anwendungsfälle abdecken sollten.
Wenn der Code Attribute im laufenden Betrieb hinzufügt, hat er wahrscheinlich (hoffentlich :-) gute Gründe dafür ... Dynamische Funktionen, Introspektion usw. zu nutzen. Abgesehen davon ist das Hinzufügen von Attributen auf diese Weise wahrscheinlich seltener, als Sie denken .
Ich würde sagen, die übliche Praxis, dies zu vermeiden, besteht darin, keine Klassen zu schreiben, in denen Sie 1000 Zeilen von irgendetwas entfernt sein können!
Im Ernst, das ist viel zu viel für jede nützliche Klasse, besonders in einer Sprache, die so ausdrucksstark ist wie Python. Wenn Sie mehr von dem, was die Standardbibliothek bietet, verwenden und Code in separate Module abstrahieren, sollten Sie Ihren LOC-Countdown beibehalten.
Die größten Klassen in der Standardbibliothek haben deutlich unter 100 Zeilen!
Instanzvariablen sollten in der Methode __init__()
der Klasse initialisiert werden. (Im Allgemeinen)
Wenn das nicht möglich ist. Sie können __dict__
verwenden, um während der Laufzeit ein Verzeichnis aller Instanzvariablen eines Objekts abzurufen. Wenn Sie dies wirklich in der Dokumentation nachverfolgen müssen, fügen Sie eine Liste der verwendeten Instanzvariablen in den Docstring der Klasse ein.
pylint kann statisch Attribute erkennen, die in __init__
nicht erkannt werden, zusammen mit vielen anderen möglichen Fehlern.
Ich würde auch empfehlen, Komponententests zu schreiben und Ihren Code oft zu benutzen, um diese Art von "whoopsie" Programmierfehlern zu erkennen.
Es klingt, als würden Sie über Instanzvariablen und nicht über Klassenvariablen sprechen. Beachten Sie, dass im folgenden Code a eine Klassenvariable und b eine Instanzvariable ist.
%Vor%Wenn Sie eine nicht benötigte Instanzvariable erstellen, weil die andere etwa 1000 Zeilen entfernt ist: Die beste Lösung besteht darin, keine Klassen zu haben, die eintausend Zeilen lang sind. Wenn Sie die Länge nicht vermeiden können, sollte Ihre Klasse einen klar definierten Zweck haben und Ihnen ermöglichen, alle Komplexitäten in Ihrem Kopf auf einmal zu behalten.
Ein Dokumentationsgenerierungssystem wie Epydoc kann als Referenz dafür verwendet werden, welche Instanz- / Klassenvariablen ein Objekt hat, und wenn Sie Sind Sie besorgt über das versehentliche Erstellen neuer Variablen über Tippfehler, können Sie PyChecker verwenden, um Ihren Code dafür zu überprüfen.
Dies ist ein häufiges Problem, das ich von vielen Programmierern höre, die aus einer C-, C ++ - oder einer anderen statisch typisierten Sprache kommen, in der Variablen vordefiniert sind. Tatsächlich war es eine der größten Sorgen, die wir hörten, als wir Programmierer in unserer Organisation davon überzeugten, C für High-Level-Programme zu verlassen und stattdessen Python einzusetzen.
Theoretisch können Sie einem Objekt zu einem beliebigen Zeitpunkt Instanzvariablen hinzufügen. Ja, das kann durch Tippfehler usw. passieren. In der Praxis führt dies selten zu einem Fehler. Wenn dies der Fall ist, sind die Fehler im Allgemeinen nicht schwer zu finden.
Solange Ihre Klassen nicht aufgebläht sind (1000 Zeilen sind ziemlich groß!) und Sie genug Unit-Tests haben, sollten Sie selten ein echtes Problem haben. Falls du dies tust, ist es einfach, zu einer beliebigen Zeit auf eine Python-Konsole zu gehen und die Dinge so oft zu untersuchen, wie du möchtest.
Es scheint mir, dass das Hauptproblem hier ist, dass Sie in C ++ denken, wenn Sie in Python arbeiten.
Eine Klasse mit 1000 Zeilen zu haben, ist in Python sowieso keine sehr weise Sache (ich weiß, dass es in C ++ viel passiert),
Lernen Sie, die Dynamik zu nutzen, die Ihnen python bietet, zum Beispiel können Sie Listen und Wörterbücher auf sehr kreative Weise kombinieren und sich Hunderte von nutzlosen Codezeilen sparen.
Wenn Sie z. B. Zeichenfolgen Funktionen zuordnen (für das Dispatching), können Sie die Tatsache ausnutzen, dass Funktionen Objekte der ersten Klasse sind und ein Wörterbuch haben, das wie folgt lautet:
%Vor%So etwas in C ++ würde sooo viele Zeilen Code aufnehmen!
Am einfachsten ist es, eine IDE zu verwenden. PyDev ist ein Plugin für Eclipse.
Ich bin kein Experte auf alle Arten Python, aber im Allgemeinen definiere ich meine Klassenmitglieder direkt unter der Klassendefinition in Python, wenn ich also Mitglieder hinzufüge, sind sie alle relativ.
Meine persönliche Meinung ist, dass die Klassenmitglieder aus diesem speziellen Grund in einem Abschnitt erklärt werden sollten.
Örtliche Bereichsvariablen, otoh, sollten am ehesten bei ihrer Verwendung definiert werden (außer in C - was meines Erachtens immer noch erfordert, dass Variablen am Anfang einer Methode deklariert werden).
Erwägen Sie die Verwendung von Slots .
Zum Beispiel:
%Vor%Es ist generell in jeder dynamischen Programmiersprache - in jeder Sprache, die keine Variablendeklaration erfordert - problematisch, dass ein Tippfehler in einem Variablennamen eine neue Variable erzeugt, anstatt eine Ausnahme auszulösen oder einen Kompilierungsfehler zu verursachen. Slots hilft bei Instanzvariablen, hilft aber nicht bei Modul-Scope-Variablen, Globalen Variablen, lokalen Variablen usw. Dafür gibt es keine Wunderwaffe; Es ist Teil des Kompromisses, Variablen nicht deklarieren zu müssen.