kostenloser Webspace werbefrei: lima-city


Python3 Skripte inkludieren

lima-cityForumProgrammiersprachenPython

  1. Autor dieses Themas

    the-8-beta

    the-8-beta hat kostenlosen Webspace.

    Hallo,

    ich arbeite zur Zeit an einem etwas umfangreicheren Pythonprojekt. Um die Übersicht zu behalten, wollte ich die Skripte so gut wie es geht modularisieren. Also pro Klasse eine Datei. Jedoch musste ich feststellen, dass die Import/From Anweisung negative Nebeneffekte hat.

    Ich suche nach einer Möglichkeit, Dateien wie in PHP zu inkludieren. Da folgende Probleme auftreten:
    1. Es reicht nicht wenn ich aus der Hauptdatei einmal alle anderen Dateien einbinde, sondern ich muss diese in jeder Datei einzelnt noch einmal importieren

    2. Eng verwandt mit Punkt 1: Ich kann nicht auf die Inhalte der Datei zugreifen, die die aktuelle Datei eingebunden hat.

    3. Resultierend aus Punk 2: Wenn ich in einer Datei eine Klasse mit statischen Attributen habe, so haben diese Attribute in allen Dateien unterschiedliche Werte, da sie nicht auf die gleiche Instanz zeigen.

    Ich kann ja verstehen, dass dieses Verhalten in vielen Fällen sehr sinnvoll ist, aber innerhalb einer Anwendung ist es vollkommen nutzlos. Daher meine Frage, gibt es noch eine andere Möglichkeit Dateien einzubinden? Oder gibt es einen Precompiler, der es ermöglicht vor dem Interpretieren aus dem Projektordner eine Datei zu erstellen?

    Hier noch ein Bsp-Programm an dem ihr das nachvollziehen könnt:
    start.py:
    from klasseb import *
    
    class My:
        foo = 6
    
    if __name__ == "__main__":
        print(My.foo)
        b = KlasseB()
        b.eineFunktion()
        print(My.foo)

    klasseb.py
    import start
    
    class KlasseB():
        def __init__(self):
            pass
    
        def eineFunktion(self):
            print(start.My.foo)
            start.My.foo += 1
            print(start.My.foo)

    Ausgabe:
    6
    6
    7
    6
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Du wirst das unten beschriebene Problem auch heben wenn du alles in einer Datei hast. Wichtig ist, dass du mit referenzen auf die Klassen arbeitest. Wenn du die referenz mit übergibst, arbeitest du immer mit der selbern instanz einer Klasse. Das ist essenziell bei der Objektorientierung. Wenn auch die statischen objektzte zugreifst erstellt du immer ein neues Klassenobjektzt was du gleich wieder verwirfst, dafür würdest du keinen Objekte benötigen.

    Du musst nicht umbedingt für jede Klasse eine Neue Datei anlegen, sinvoller ist eine Klare struktur. Klassen die sehr nach aneinander liegen in ein Modul.


    Was die vielen imports angeht: Benutzte dafür doch eine IDE wie pycharm, die kümmert sich um soetwas automatisch.


    Ein Precompiler würde alles nur sehr unübersichtlich machen
  4. Autor dieses Themas

    the-8-beta

    the-8-beta hat kostenlosen Webspace.

    Du musst nicht umbedingt für jede Klasse eine Neue Datei anlegen, sinvoller ist eine Klare struktur. Klassen die sehr nach aneinander liegen in ein Modul.

    Ja pro klasse eine Datei war etwas übertrieben formuliert. Jedoch hatte ich Anwendungsfälle bei denen das skript über 4500 Zeilen umfasste. Da ist es trotz objektorientierung schwierig die Übersicht zu behalten, selbst wenn man in IDEs wie PyCharm ganze Codeblöcke einklappen kann.
    Es funktioniert leider nur selten, dass man innerhalb einer Anwendung Teile in ein Modul outsourcen kann. Das ist meistens der Fall wenn man mit Threads und serieller Kommunikation arbeitet. Oder auch wenn man mit GUIs arbeitet, z.b. mit PyQt wird es schwierig bzw. nervig Code in einzelne Module auszugliedern.

    Ein Precompiler würde alles nur sehr unübersichtlich machen

    Wieso? Wäre doch nur eine Zeile. Ich könnte mir folgende Syntax vorstellen:
    #---INCLUDE klassea.py
    Es würde es umständlicher machen, das gebe ich gerne zu. Doch es wäre übersichtlicher als eine Datei mit 5000 Zeilen Code.

    Ich hab mir heute nochmal ein paar Gedanken gemacht und mir ist ein Workaround eingefallen, der mir zwar nicht gefällt, aber prinzipiell funktioniert.
    my_globals = globals()
    
    def include(path):
        global my_globals
        f = open(path)
        code = f.read()
        f.close()
        exec(code, my_globals)
    
    include("klasseb.py")
    include("main.py")

    Ist nicht schön, aber erfüllt den Zweck. Bringt auch den Nachteil mit sich, dass die Fehlermeldungen vom Debugger unsauberer werden. Ich weiß noch nicht, ob ich dieses Workaround jemals nutzen werde, doch vlt. ist ja noch jemand anderes daran interresiert.
  5. Ich glaube du geht die Dinge falsch an. Inkludieren von Quellcode ist längst nicht mehr gängige Praxis. PHP hat das auch nur so gemacht, weil C es auch so gemacht hat und PHP ein Hypertext-Präprozessor sein will. Moderner PHP Code verwendet Namespaces anstatt alle Funktionen und Klassen im gleichen Namensraum zu haben.

    Gerade wenn es darum geht große Projekte zu managen sind Namespaces und Module wichtige Werkzeuge, um Code zu organisieren. Natürlich ist es nicht immer einfach zu entscheiden, in welche Datei man eine bestimmte Funktion packen sollte. Aber wenn es nur um ein persönliches Projekt geht, kann man sich auch jederzeit neu entscheiden die Funktion in eine andere Datei zu packen.

    Es mag für dich zunächst umständlich erscheinen am Anfang einer Quellcode-Datei ganz viele import-Anweisungen zu notieren, aber glaube mir, daran gewöhnt man sich recht schnell. Wie einer meiner Vorposter bereits sagte, kann einem eine IDE auch dabei helfen diese Importlisten zu pflegen. Ich selber programmiere recht viel in Python und habe kein nennenswertes Problem damit meine Importlisten per Hand zu pflegen.

    Der Wildcard-import "from Modul import *" genießt in der Python-Community keinen guten Ruf. Es gibt Situationen wo er sinnvoll ist, aber diese Situationen sind eher selten. Du kannst durch Wildcard-Importe Namenskollisionen erzeugen, wenn in verschiedenen Modulen gleichnamige Funktionen oder Klassen vorkommen. Besser ist ein "import Modul" oder wenn du Tipparbeit sparen willst, definiere einfach einen kürzeren Modul-Alias: "import Modul as mod". Dann musst du zwar immer noch schreiben "mod.meine_funktion()" aber dadurch ist dann eindeutig festgelegt, dass meine_funktion in dem Modul "Modul" bzw. "mod" definiert ist und man weiß dann auch in welche Datei man reinschauen muss, wenn man die Funktion verändern will.

    Du wirst dir jetzt vielleicht denken: Was soll das, ich weiß doch was ich tue? Momentan magst du das wissen, aber in der nicht so fernen Zukunft wirst du möglicherweise noch einmal mit diesem Code zu tun haben und dann einiges Vergessen haben. Und dann ist es wesentlich schwerer zu verstehen, was der Code eigentlich tut.

    Code wird in der Regel viel häufiger gelesen als geschrieben. Das mag dir eventuell noch nicht bewusst sein, aber es lohnt sich sich über sein eigenes zukünftiges Ich (oder andere Leser deines Quellcodes) Gedanken zu machen, die versuchen werden deinen Code zu verstehen um z.B. einen Bug zu fixen.

    Siehe dazu auch die Philosophie von Python:
    python -m this


    Von daher: Kämpfe nicht gegen deine Programmiersprache an. Nutze die Infrastruktur die Python dir bietet und versuche nicht PHP-Code in Python zu schreiben. Da wirst du dir nur selbst Schmerzen bereiten.

    Beitrag zuletzt geändert: 24.3.2015 22:21:01 von bladehunter
  6. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!