Seite 1 von 1

Anfängerfrage: Import eigener *.py

Verfasst: Samstag 22. April 2017, 17:50
von CoderGirl
Hallo,

ich habe eine eigene base.py geschrieben, die ich auch erfolgreich in meine main.py
importiere und benutzen kann.
Nur habe ich das Problem, dass ich beim Ändern dern base.py die Änderungen nicht
nutzen kann, da die Funktionen nicht verfügbar sind.
Speicher ich unter neuem Namen ab und imprtiere diese "neue" base.py dann
klappt es und es sind auch die Änderungen da.
Irgendetwas muss ich sicher als Zwischenschritt machen, aber bin da ein wenig ratlos :K

Danke

lg
codergirl

Re: Anfängerfrage: Import eigener *.py

Verfasst: Samstag 22. April 2017, 18:03
von Alfons Mittelmeyer
Also bei mir funktioniert es. Änderst Du vielleicht diese base.py während Python noch läuft? Mehrfachimport geht nicht.

Ansonsten müßte man das näher untersuchen. Im Subverzeichnis __pycache__ gibt es dann eine Datei, die etwa heißen könnte: base.cpython-34.pyc, jedenfalls mit base anfängt.

Lösche die einfach mal raus.

Normalerweise sollte python mitbekommen, dass ein Änderung gemacht wurde und neu übersetzen anstatt das bereits compilierte Modul zu nehmen. Warum es das bei Dir nicht mitbekommt, weiss ich nicht.

Re: Anfängerfrage: Import eigener *.py

Verfasst: Samstag 22. April 2017, 18:22
von kbr
@codergirl: Führst Du den Import vom interaktiven Terminal aus? Ein reimport ist seit Python3 nicht mehr vorgesehen. Wenn Du von der Kommandozeile aus mit 'python main.py' das Modul 'main.py' ausführst, sollte der import einwandfrei funktionieren.

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 05:59
von CoderGirl
Hallo,

einen wunderschönen guten Morgen!

Ich nutze Python über den Scripteditor eines GIS-Systems.
Mglw. liegt es an dem genannten Re-Import, der dann nicht mehr klappt.

Naja, dann ändere ich sie halt sukzessive ab und lade sie jeweils über einen
neuen Namen ein: Ist jetzt auch kein Riesenaufwand!

Ging mir nur drum, warum ich es mir nicht erklären konnte, warum

Vielen Dank

lg
codergirl

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 11:57
von pixewakb
Klingt nicht nach einer brauchbaren Lösung. Auf mittlere Sicht - falls Du gerade mit Python startest - wirst Du mehr und mehr Bibliotheken nutzen müssen, d. h. das wird dann irgendwann nicht mehr gangbar sein. Kann das ein Problem des GIS-Systems sein? Hast Du mal andere Anwender (Kolleginnen und Kollegen) gefragt, wie sie das Problem lösen?

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 12:49
von Alfons Mittelmeyer
@CoderGirl: Wenn das Gis System ein Python Programm ist und nicht nach Ändern des Moduls Heruntergefahren und wieder gestartet werden soll, dann gibt ves auch noch eine andere Lösung.

Mit dieser habe ich sehr gute Erfahrungen gemacht. Sie ist aber in diesem Forum verpönt. Man importiert kein Modul sondern lädt ein Script nach.

Das Script muss dann auch etwas anders aussehen, als ein Modul. Alles was im Modul war, muss dann in eine Klasse eingerückt werden, etwa:

Code: Alles auswählen

class Access():

    def __init__(self):
        self.var1 = "Test 1"  # base.var1

    def output(self): # base.output
        print(self.var1)
Im Main Script kann man das nachladen und darauf zugreifen:

Code: Alles auswählen

def dyn_access(filename):
    exec(compile(open(filename, "r").read(), filename, 'exec'))
    return locals()['Access']()


base = dyn_access('base.py')

base.output()
base.var1 = "Test 2"
base.output()

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 13:02
von Sirius3
@Alfons Mittelmeyer: jetzt solltest Du noch verraten, was der Unterschied zwischen einem Skript und einem Modul ist. Ob es Klassen gibt oder nicht, spielt dabei nämlich keine Rolle.
Und auch Dein kompliziertes Konstrukt verhindert nicht, dass Module nur einmal geladen werden und bei Veränderung nicht nocheinmal.

Das einfachere

Code: Alles auswählen

base = reload(base)
macht das selbe, ohne irgendwelche unsinnigen Klassen einführen zu müssen. Das Problem bleibt, das ArcGIS eine Pythonumgebung in seiner Shell hat und es deswegen zu Seiteneffekten kommt.

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 14:00
von kbr
@CoderGirl: das von Sirius3 gezeigte

Code: Alles auswählen

reload(base)
funktioniert in Python2. In Python3 ist diese Funktion entfallen, kann aber weiterhin importiert werden:

Code: Alles auswählen

import imp
imp.reload(base)
Zwischenzeitlich aus base.py entfernte Objekte können im importierten Namespace dabei aber erhalten bleiben. Ob das für Deine GIS Umgebung hilfreich ist, kann ich leider nicht beantworten.

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 15:15
von CoderGirl
Hallo

herzlichen Dank.

Ich probiere das umgehend mal aus.

Danke euch

codergirl

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 15:55
von Alfons Mittelmeyer
Sirius3 hat geschrieben:@Alfons Mittelmeyer: jetzt solltest Du noch verraten, was der Unterschied zwischen einem Skript und einem Modul ist. Ob es Klassen gibt oder nicht, spielt dabei nämlich keine Rolle.
Und auch Dein kompliziertes Konstrukt verhindert nicht, dass Module nur einmal geladen werden und bei Veränderung nicht nocheinmal.
Wenn imp.reload klappt, ist das die Beste Lösung.

Was der Unterschied zwischen Scriptund Modul ist?

Der Code des Moduls wird beim ersten import ausgeführt und außerdem wird daraus etwas fest in den Speicher geladen, das wie ein Objekt - also wie eine instanzierte Klasse mit Punkt Operator ansprechbar ist.

Weiter imports führen dann den Code nicht mehr aus, sondern liefern nur eine Referenz auf dieses Modulobjekt also immer nur gewissermaßen auf dieselbe Instanz. Dadurch können auch Zustände global über das Modul übergeben werden.


Mit read und exec dagegen wird das Script immer ausgeführt, und wenn es sich geändert hat, dann wird das geänderte Script ausgeführt. Werden Namen in diesem Script definiert, so sind sie nur lokal für die aufrufende Funktion - hier dyn_access - verfügbar. Der Zugriff muss aber dann mit locals()['name'] erfolgen.

Damit etwas vom Script nach Ausführung übrigbleibt, instanziert meine Funktion ein Objekt der Klasse Access des Scripts und gibt die Referenz darauf zurück. Dieses Objekt ist nicht global vorhanden, sondern wird lediglich an eine Variable (hier base) gebunden.

Wenn andere Module auch auf dieselbe Instanz zugreifen möchten, müße man ihnen diese Referenz namens base übergeben. Wenn andere Module selber auch diese Funktion dyn_access aufrufen würden, erhielten sie eine eigene Instanz. Datenaustausch mit anderen Modulen oder globale Zustände über so ein Script müßte in diesem Fall über ein weiteres Modul erfolgen, das vom Script importiert wird.

Also, wenn imp.reload funktioniert, dann jedenfalls imp.reload nehmen.

Meine Scripts mittels dyn_access sind eigentlich nicht als Modulersatz gedacht, sondern für manchmal zusätzlich benötigte Aufgaben, bei denen nach Ausführung die dafür verwendeten Objekte wieder beseitigt werden. Es geht dabei also um etwas, das man nur lokal und temporär gelegentlich braucht. Eine modulähnliche Verwendung wäre machbar, aber sollte man wegen dem zusätzlichen Aufwand nicht tun, wenn es auch auf die für Module normale Weise geht.

Hoppla, man könnte natürlich dieses dyn_access auch in ein Modul legen und mit einer weiteren Funktion dafür sorgen, dass andere Module dann eine Referenz bekommen, wenn schon eine Instanz existiert. Also kann man es doch wie ein Modul machen. Lediglich bleibt dann der Aufwand, dass man dann aus einem Modulinhalt händisch eine Klasse machen muss, während ein import das schon selber erledigt.

Re: Anfängerfrage: Import eigener *.py

Verfasst: Sonntag 23. April 2017, 16:28
von CoderGirl
Hallo zusammen,

ich halte euch auf dem laufenden.
Hocke mich eh die Woche nochmal dran :)

lg
codergirl