Hi
ich muss für die Uni ein Programm zur Auswahl von Kellern in ArcGis
schreiben und habe da jetzt ewig lang Codes bzw ein ewig langes Skript.
Da ich mich nicht so gut mit Python auskenne bräuchte ich jetzt Hilfe:
um das etwas handlicher zu machen, hab ich mir gedacht, das Programm als
Modul in einem übersichtlicheren Skript aufzurufen. Da das aber nach dem
Schema if,elif,else funktioniert, geht das mit import modulname nicht...
Jetzt habe ich gelesen, dass man globale Variablen definieren kann, aber
entweder mach ich das falsch oder es geht aucht nicht.
Das sieht jetzt so aus:
def foo(a):
global a
a = 2
import sys
sys.path.append('C:\Python27')
import modulname
Kann mir jemand weiterhelfen oder hat jemand andere Vorschläge wie man
das "schön" machen könnte?
naj schrieb:> so hab ichs ja eigentlich auch gemacht...
Dann versteh ich leider nicht, warum du das anders machen willst bzw. wo
dein Problem mit dieser Methode ist :-(
So ganz verstehe ich auch nicht, was du vorhast. Wie es scheint,
möchtest du die Variable a mit einem Wert an das Modul übergeben, so
dass sie dort als globale Variable gelesen werden kann. Das geht
so aber nicht, da importierte Module aus gutem Grund keine Variablen vom
importierenden Programm übernehmen.
Eine Möglichkeit wäre, das Modul nicht zu importieren, sondern mit
execfile() auszuführen. Dann wird der Code des Moduls in der gleichen
Ebene wie das importierende Programm ausgeführt und kann damit auch auf
die Variable a zugreifen. Aber sehr "schön" ist diese Methode nicht ;-)
Vielleicht hilft es unserem Verständnis auf die Sprünge, wenn du ein
einfaches Beispiel konstruierst, aus dem ersichtlich ist, was das Modul
tut und wie du es in dem übergeordneten Programm verwenden möchtest.
sorry war den Abend über weg...
ich beschreib es jetzt noch mal genauer :)
a = ?
# das Fragezeichen durch die Nummer des gewünschten Komplexes ersetzen
if a == 0:
arcpy.SelectLayerByAttribute_management ("ktreppe","NEW_SELECTION",
" KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kgang","NEW_SELECTION", "
KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kpfeiler","NEW_SELECTION",
" KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kraum","NEW_SELECTION", "
KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kschacht","NEW_SELECTION",
" KKOMPLEXID = 0")
das Problem ist, dass es 341 verschiedene a's (Kellerkomplexe) gibt und
das halt nicht sehr schön aussieht und auch in dem Programm extrem
hängt. Deshalb war meine Idee, das der Endnutzer im Prinzip nur noch
sieht:
a = ?
deshalb dachte ich, dass man das vlt mit import lösen könnte. Ich werde
mir jetzt mal dieses execfile anschauen, ich hab halt gar keine
Erfahrung mit Programmieren, deshalb kann ich mich da noch nicht so
ausdrücken und versteh vieles nicht. Deshalb bin ich euch sehr dankbar
für eure Hilfe!
exec( "C:\Python27\dateiname.pyw",
{'a': ?})
# das Fragezeichen durch die Nummer des gewünschten Komplexes ersetzen
so funktioniert es und sieht doch gar nicht schlecht aus! :)
naj schrieb:> if a == 0:> arcpy.SelectLayerByAttribute_management ("ktreppe","NEW_SELECTION",> " KKOMPLEXID = 0")
D.h. die Anweisungen in dem Modul stehen frei und sind nicht in einer
Funktion oder eine Methode zusammengefasst?
Dann ist das auch kein "richtiges" Modul¹, und es ist in diesem Fall
durchaus in Ordnung, den Code mit execfile auszuführen, wie du es ja
erfolgreich gemacht hast.
Eine andere Möglichkeit wäre, das Ganze in eine Funktion mit einem
Argument zu packen, also etwa so:
kellermodul.py:
1
def kellerfunktion(a):
2
if a == 0:
3
...
4
elif a == 1:
5
...
6
...
main.py
1
from kellermodul import *
2
3
kellerfunktion(2)
———————————————
¹) Üblicherweise bestehen Module nur aus Klassen und Funktionen. Nur
die Anweisungen für eine evtl. erforderliche Modulinitialisierung
stehen frei, da sie beim Importieren des Moduls genau einmal aus-
geführt werden sollen.
Yalu X. schrieb:> Eine andere Möglichkeit wäre, das Ganze in eine Funktion mit einem> Argument zu packen, also etwa so:>> kellermodul.py:>
1
> def kellerfunktion(a):
2
> if a == 0:
3
> ...
4
> elif a == 1:
5
> ...
6
> ...
7
>
>> main.py>
1
> from kellermodul import *
2
>
3
> kellerfunktion(2)
4
>
Das ist im Gegensatz zu dem 'import' Gefrickel mal ein vernünftiger
Vorschlag.
@naj: Wenn Du etwas mehr Lust hast Dich mit Python zu beschäftigen, dann
beschäftige Dich mal mehr mit Schleifen und vorallendingen, sehr sehr
nützlich: Dictionaries. Damit kann man in Python sehr gut wartbaren
kompakten und verständlichen Code schreiben. Gerade solche
If-Abfrage-Ketten bei denen nur unterschiedliche Felder ausgewählt
werden sollen sind so schon fast trivial. Beispiel:
1
kellerkomplexe = {
2
0 : "ktreppe kgang kpfeiler kraum kschacht",
3
}
4
5
def kellerfunction(a):
6
for x in kellerkomplexe[a].split():
7
arcpy.SelectLayerByAttribute_management(x,"NEW_SELECTION","KKOMPLEXID = %u" % a)
Oder ist ktreppe, kgang bei jeder komplexid auszuwählen? Dann wirds
trivial, aber das darfst Du selbst herausfinden.
danke für die Tipps! Mein Problem war auch die ganze Zeit, dass ich
nicht weiß wonach ich überhaupt suchen muss, aber jetzt kann ich ja gut
drauf aufbauen :)
naj schrieb:> wenn mir noch jemand sagen könnte für was das * nach import steht wäre> ich wunschlos glücklich!
[Glaskugel] * ist ein Platzhalter für "Alles". Also import * -->
importiere alles
Es gibt in Python mehrere Möglichkeiten, ein Modul oder Teile davon zu
importieren.
Variante 1:
1
import <Modul>
Bei der Verwendung von Von Klassen/Funktionen/Variablen aus dem Modul
muss immer der Modulname vorangestellt werden:
1
import kellermodul
2
3
kellermodul.kellerfunktion(2)
Variante 2:
1
from <Modul> import <Element 1>, <Element 2>, ...
Es werden nur die Klassen/Funktionen/Variablen <Element 1>, <Element 2>
usw. importiert. Sie werden ohne vorangestellten Modulnamen verwendet:
1
from kellermodul import kellerfunktion
2
3
kellerfunktion(2)
In dieser Variante können Elemente beim Importieren mit as umbenannt
werden, um Namenskonflikte zu vermeiden:
1
from kellermodul import kellerfunktion as untergeschossfunktion
2
3
untergeschossfunktion(2)
Variante 3:
1
from <Modul> import *
Es werden alle Klassen/Funktionen/Variablen importiert. Sie werden ohne
vorangestellten Modulnamen verwendet:
1
from kellermodul import kellerfunktion
2
3
kellerfunktion(2)
Diese letzte Variante ist die schreibfaulste. Bei Modulen mit vielen
Elementen besteht aber die Gefahr von Namenskonflikten, da dem Namens-
raum viele einzelne Namen hinzugefügt werden. Das in deinem Fall aber
wahrscheinlich kein Problem.
Jetzt war ich heut in der Uni und wollte das ausprobieren und es kamen
folgende Error meldungen:
Runtime error
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named kellermodul
dabei befindet sich die Datei im selben Ordner.
dann hab ich mal nur eingegeben:
import arcpy
arcpy.SelectLayerByAttribute_management ("ktreppe","NEW_SELECTION",
" KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kgang","NEW_SELECTION", "
KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kpfeiler","NEW_SELECTION",
" KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kraum","NEW_SELECTION", "
KKOMPLEXID = 0")
arcpy.SelectLayerByAttribute_management ("kschacht","NEW_SELECTION",
" KKOMPLEXID = 0")
dann kam "Parsing error IndentationError: unexpected indent (line 2)"
jetzt hab ich das Zuhause noch mal probiert und hier kommen plötzlich
die selben Fehlermeldungen...was ist denn jetzt schon wieder los?
naj schrieb:> Jetzt war ich heut in der Uni und wollte das ausprobieren und es kamen> folgende Error meldungen:>> Runtime error> Traceback (most recent call last):> File "<string>", line 1, in <module>> ImportError: No module named kellermodul
Was hast du da genau gemacht? 'File "<string>"' sieht so aus, als
hättest du
1
exec('import kellermodul')
o.ä. ausgeführt.
> dabei befindet sich die Datei im selben Ordner.
Schau mal, ob sys.path einen Leerstring ('') als Element enthält:
1
import sys
2
print sys.path
Dann sollte auch das Verzeichnis des aufrufenden Moduls nach Modulen
durchsucht werden.
> dann hab ich mal nur eingegeben:>> import arcpy> arcpy.SelectLayerByAttribute_management ("ktreppe","NEW_SELECTION",> ...>> dann kam "Parsing error IndentationError: unexpected indent (line 2)"
Die zweite Zeile (arcpy...) darf nicht eingerückt sein. Python ist
einrückungssensitiv.
jetzt funktioniert es wieder, ich hab jetzt beide dateien mal in den
Pythonordner verschoben...komisch
Jetzt wollte ich mich mal mit Schleifen Dictionaries Sache auseinander
setzen,
Die Zeile "kellerkomplexe = {0 : "ktreppe kgang kpfeiler kraum
kschacht",}"
kann ich nachvollziehen.
" for x in kellerkomplexe[a].split():
arcpy.SelectLayerByAttribute_management(x,"NEW_SELECTION","KKOMPLEXID
= %u" % a)"
heißt, dass x zB. ktreppe kgang kpfeiler kraum und kschacht entspricht
und dann der selektionsbefehl in die 5 verschiedenen aufgeteilt wird
oder?
aber was dann %u" % a bedeutet weiß ich nicht