Moin Leute.
Ich spiele zurzeit ein bisschen mit der Skriptsprache Python3 herum.
Ich arbeite überwiegend mit einem Texteditor und der Ubuntu-Konsole.
Ich habe jetzt ein Skript geschrieben, was die Fakultät berechnet.
Ich starte es mit python3 fac.py (fac.py ist die Datei mit dem Code)
Es wird anscheint fehlerfrei ausgeführt, aber es passiert dann nichts
weiter. Wie übergebe ich der Funktion den Wert? Oder muss ich für die
Variable n, schon im Skript vorher eine Zahl einsetzen?
Bin irgendwie verzweifelt....
Nicht nur Funktionen, sondern auch einem Python-Skript kann man
Argumente übergeben. Ruft man ein Python-Skript aus einer Shell auf,
werden die Argumten jeweils durch ein Leerzeichen voneinander getrennt
hinter dem Skriptnamen aufgeführt. Im Python-Skript selber sind diese
Argumente unter der Listenvaribale sys.argv abrufbar. Der Name des
Skriptes (Dateiname) ist unter sys.argv[0] erreichbar.
Das Skript (argumente.py) listet sämtliche mitgegebenen Argumente in der
Standardausgabe auf:
# Modul sys wird importiert:
import sys
# Iteration über sämtliche Argumente:
for eachArg in sys.argv:
print eachArg
Beispiel eines Aufrufes, falls das Skript unter argumente.py gespeichert
worden ist:
python argumente.py python kurs fuer anfaenger
Dieser Aufruf erzeugt folgende Ausgabe
argumente.py
python
kurs
fuer
anfaenger
Ok. Danke erstmal.
Also zum Beispiel:
python3 fac.py 5
würde dann 5! = 120 berechnen/ausgeben? Sitz morgen erst wieder am
Rechner und kann es noch nicht ausprobieren.
nicht“Gast„ schrieb:> print eachArg
Das funktioniert in Python 3 aber nicht.
Python-Rookie schrieb:> Ich starte es mit python3 fac.py
Ja, kann man so machen, schöner ist aber das Script ausführbar zu machen
und eine Shebang Zeile an den Anfang zu setzten.
1
#!/usr/bin/env python
2
# Das da oben nennt sich Shebang-Zeile
3
4
5
importsys
6
7
8
deffak(x):
9
y=1
10
foriinrange(1,x+1):
11
y=y*i
12
13
returny
14
15
16
if__name__=='__main__':
17
iflen(sys.argv)!=2:
18
print('Invalid Numbers of Arguments. Script will be terminated.')
Das argv hat nicht“Gast„ schon erklärt. Hier sind noch ein paar weitere
Hilfsmittel:
Mit int() kannst du einen String in einen Zahlenwert konvertieren, mit
dem sich rechnen lässt. Falls der String nicht die ASCII-Repräsentation
einer Zahl enthält, wird eine ValueError-Exception ausgelöst. Wenn auf
ein Element außerhalb der Array-Grenzen zugegriffen wird, gibt's einen
IndexError. Beide Fehler kann man über ein Try-Except-Konstrukt
abfangen¹.
Hier ein Beispiel:
1
from sys import argv
2
from math import factorial
3
4
try:
5
n = int(argv[1])
6
except IndexError:
7
print('missing argument')
8
except ValueError:
9
print('argument must be an integer')
10
else:
11
if n >= 0:
12
print('%d! = %d' % (n, factorial(n)))
13
else:
14
print('argument must be non-negative')
Aufruf und Ausgabe:
1
$ python3 fac.py 30
2
30! = 265252859812191058636308480000000
—————————————
¹) Der IndexError ließe sich auch dadurch vermeiden, dass man die Anzahl
der Argumente mit len(argv)>=2 abprüft. Wenn man aber sowieso ein Try
verwendet, kann man auch gleich beide Fehler damit abfangen.
Yalu X. schrieb:> Das argv hat nicht“Gast„ schon erklärt. Hier sind noch ein paar> weitere> Hilfsmittel:>> Mit int() kannst du einen String in einen Zahlenwert konvertieren, mit> dem sich rechnen lässt. Falls der String nicht die ASCII-Repräsentation> einer Zahl enthält, wird eine ValueError-Exception ausgelöst. Wenn auf> ein Element außerhalb der Array-Grenzen zugegriffen wird, gibt's einen> IndexError. Beide Fehler kann man über ein Try-Except-Konstrukt> abfangen¹.>> Hier ein Beispiel:> from sys import argv> from math import factorial>> try:> n = int(argv[1])> except IndexError:> print('missing argument')> except ValueError:> print('argument must be an integer')> else:> if n >= 0:> print('%d! = %d' % (n, factorial(n)))> else:> print('argument must be non-negative')>> Aufruf und Ausgabe:> $ python3 fac.py 30> 30! = 265252859812191058636308480000000
Oha. Das sieht doch für mich erstmal ein bisschen kompliziert aus. Gibt
es nicht schöneren Code :) ?
Python-Rookie schrieb:> Ok. Danke erstmal.>> Also zum Beispiel:>> python3 fac.py 5>> würde dann 5! = 120 berechnen/ausgeben? Sitz morgen erst wieder am> Rechner und kann es noch nicht ausprobieren.
Das würde nicht funktionieren?
Kaj schrieb:> Python-Rookie schrieb:>> Gibt es nicht schöneren Code :) ?> Hab ich doch da oben gepostet D:> Ignoranten... :P>> Beitrag "Re: Python-Skript starten über Konsole, wie Parameter> übergeben?"
Wenn ich mein Skript anpasse, sollte das denn funktionieren? Sieht auch
seltsam aus, aber nicht so abstrakt wie vom nachfolgenden Post.
Könnt ihr mir sonst eine IDE empfehlen für Python? Kann ich damit das
Problem zu Not umgehen? Ich dachte Python ist einfach...
Python-Rookie schrieb:> Oha. Das sieht doch für mich erstmal ein bisschen kompliziert aus. Gibt> es nicht schöneren Code :) ?
Ich wollte dir bei der Gelegenheit nur gleich zeigen, wie man das
Programm robust gegenüber fehlerhaften Eingaben wie bspw.
1
fac
2
fac sjdfg
3
fac 4.5
4
fac -1
macht. Klar, für den Anfang kannst du die ganzen Abfragen auch erst
einmal weglassen :)
Kaj schrieb:> #!/usr/bin/env python
Noch besser ist:
1
#!/usr/bin/env python3
In manchen Distributionen zeigt "python" (ohne angehängte Ziffer)
nämlich noch auf "python2".
Python-Rookie schrieb:> Sieht auch seltsam aus, aber nicht so abstrakt wie vom nachfolgenden> Post.
Die übersichtlichste Version (allerdings ohne jegliche Fehlerabfrage)
sieht etwa so aus:
Yalu X. schrieb:> Python-Rookie schrieb:>> Sieht auch seltsam aus, aber nicht so abstrakt wie vom nachfolgenden>> Post.> Die übersichtlichste Version (allerdings ohne jegliche Fehlerabfrage)> sieht etwa so aus:> from sys import *> from math import *> n = int(argv[1])> print(factorial(n))>> die kürzeste so:>> from sys import *> from math import *> print(factorial(int(argv[1])))
Danke. Das sieht gut aus. Ich werde das dann mit meiner Methode
anpassen. Was macht denn hier eigentlich argv[1]?
Python-Rookie schrieb:> Was macht denn hier eigentlich argv[1]?argv ist eine Liste von Strings mit den Kommandozeilenargumenten.
Diese Variable wird beim Start eines Python-Skripts automatisch vom
Laufzeitsystem mit Inhalt gefüllt. Dabei ist das erste Element (argv[0])
der Name des aufgerufenen Python-Skripts, die restlichen Elemente
(argv[1], argv[2], ...) sind die nachfolgenden Argumente. Da das aber
alles Strings und keine Zahlenwerte sind (je nach Anwendung möchte man
ja beliebige Wörter als Kommandozeilenargumente übergeben), müssen die
Argumente ggf. mit der int()-Funktion in Zahlen umgewandelt werden.
Python-Rookie schrieb:> Oha. Das sieht doch für mich erstmal ein bisschen kompliziert aus. Gibt> es nicht schöneren Code :) ?
Ja, da gibt es das Modul "argparse". Beispiel:
In "args.zahl" befindet sich jetzt der erste Parameter als Integer. Wenn
kein Parameter angegeben wurde oder der erste Parameter (siehe hierzu in
der Dokumentation von argparse unter "positional argument") kein Integer
ist, wird eine ordentliche Fehlermeldung ausgegeben. Auf der
Python-Webseite gibt es zum argparse-Modul eine Dokumentation und ein
Tutorial, bei pymotw.com weitere ausführliche Dokumentation. Außerdem
gibt es in Python auch noch weitere Module zum Parsen der Kommandozeile,
etwa eine Implementierung der bekannten C-Bibliothek optparse, die ich
weder unter C noch unter Python sonderlich elegant finde. Ich persönlich
finde argparse allerdings sehr elegant und übersichtlich -- YMMV.
Python-Rookie schrieb:> Wenn ich mein Skript anpasse, sollte das denn funktionieren? Sieht auch> seltsam aus, aber nicht so abstrakt wie vom nachfolgenden Post.>> Könnt ihr mir sonst eine IDE empfehlen für Python?
Ein guter Texteditor reicht. Für alte UNIX-Hasen sind vi(m) oder Emacs
immer einen Blick wert, Jüngere nutzen unter Linux gerne Kate, Sublime,
Atom oder Geany.
> Kann ich damit das Problem zu Not umgehen?
Mit einer IDE? Nein, auch in Python mußt Du immer noch selbst
programmieren.
> Ich dachte Python ist einfach...
Ist es auch. Aber lern' doch erstmal die Grundlagen und schau Dich dann
mal in der Standardbibliothek um, dann wirst Du sehr schnell
feststellen, wie einfach Python ist und wieviel Arbeit es Dir abnehmen
kann. Was Yalu Dir da als Beispiel mit ausführlichem Exception-Handling
gezeigt hat, würde ein erfahrener Python-Entwickler nie machen. ;-)
Danke euch erstmal für die Hilfe und Tipps. Es hat gut geklappt. Hätte
nur nicht gedacht, dass das so umständlich ist mit Parametern
eingeben.....
Bei C++ macht man das ja mit cin....
Ich werde dann mal weiter meine Kenntnisse in Python vertiefen....
Python-Rookie schrieb:> Danke euch erstmal für die Hilfe und Tipps. Es hat gut geklappt. Hätte> nur nicht gedacht, dass das so umständlich ist mit Parametern> eingeben.....>> Bei C++ macht man das ja mit cin....
Damit liest du aber nicht die Kommandozeilenargumente. Diese werden auch
in C[++] über das argv-Array gelesen. Das sieht dann etwa so aus: