Forum: PC-Programmierung Python-Skript starten über Konsole, wie Parameter übergeben?


von Python-Rookie (Gast)


Lesenswert?

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....

von nicht“Gast„ (Gast)


Lesenswert?

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

von Python-Rookie (Gast)


Lesenswert?

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.

von Kaj (Gast)


Lesenswert?

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
import sys
6
7
8
def fak(x):
9
    y = 1
10
    for i in range(1, x + 1):
11
        y = y * i
12
13
    return y
14
15
16
if __name__ == '__main__':
17
    if len(sys.argv) != 2:
18
        print('Invalid Numbers of Arguments. Script will be terminated.')
19
    else:
20
        arg = int(sys.argv[1])
21
        f = fak(arg)
22
        print('Faculty of {0} is: {1}'.format(arg, f))

Dann kannst du das Script einfach über
1
./my_script.py
 ausführen und ein Argument übergeben
1
./my_script 5
2
Faculty of 5 is: 120

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

: Bearbeitet durch Moderator
von Python-Rookie (Gast)


Lesenswert?

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 :) ?

von Python-Rookie (Gast)


Lesenswert?

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?

von Kaj (Gast)


Lesenswert?

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?"

von Python-Rookie (Gast)


Lesenswert?

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...

von Yalu X. (yalu) (Moderator)


Lesenswert?

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".

von Yalu X. (yalu) (Moderator)


Lesenswert?

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:

1
from sys import *
2
from math import *
3
4
n = int(argv[1])
5
print(factorial(n))

die kürzeste so:

1
from sys import *
2
from math import *
3
print(factorial(int(argv[1])))

: Bearbeitet durch Moderator
von Python-Rookie (Gast)


Lesenswert?

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]?

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Kaj (Gast)


Lesenswert?

Python-Rookie schrieb:
> Sieht auch seltsam aus
Was genau sieht denn für dich seltsam aus?
Beschreibe dein Problem, dann können wir dir vielleicht auch helfen. :)
Wenn du vernünftige Fragen stellst, reißt dir hier auch keiner den Kopf 
ab.

Python-Rookie schrieb:
> Ich dachte Python ist einfach...
Ist es auch, wenn man es (halbwegs) verstanden hat.

Python-Rookie schrieb:
> Könnt ihr mir sonst eine IDE empfehlen für Python?
Eclipse mit Python-Plugin ist weit verbreitet.
Darüber hinaus gibt es noch eric6, pycharm, wingide (kostet!)...

eric6:
http://eric-ide.python-projects.org/eric-download.html

PyCharm:
https://www.jetbrains.com/pycharm/

WingIDE:
http://www.wingware.com/

Ich denke, dass sind so die üblichsten IDEs.

Ansonsten kann ich dir dieses Buch sehr empfehlen,
um in Python reinzukommen:
https://www.amazon.de/Python-umfassende-Sprachgrundlagen-Objektorientierung-Modularisierung/dp/3836236338/ref=sr_1_1?ie=UTF8&qid=1473797073&sr=8-1&keywords=python+3

von nixwasigenau (Gast)


Lesenswert?

Auch im web gibts gutes ...
http://www.python-kurs.eu/index.php

von Sheeva P. (sheevaplug)


Lesenswert?

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:
1
import argparse
2
3
if __name__ == '__main__':
4
  parser = argparse.ArgumentParser(description="mein tolles Programm")
5
  parser.add_argument('zahl', type=int, help="berechne Fakultät")
6
  args = parser.parse_args()

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.

von Sheeva P. (sheevaplug)


Lesenswert?

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. ;-)

von Python-Rookie (Gast)


Lesenswert?

nixwasigenau schrieb:
> Auch im web gibts gutes ...
> http://www.python-kurs.eu/index.php

Danke, den arbeite ich gerade durch. Daher habe ich auch das Beispiel 
der Fakultätsfunktion.

von Python-Rookie (Gast)


Lesenswert?

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....

von Yalu X. (yalu) (Moderator)


Lesenswert?

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:

1
#include <cstdlib>
2
3
int main (int argc, char *argv[]) {
4
  int n = atoi(argv[1]);
5
  // ...
6
  return 0;
7
}

von Kaj (Gast)


Lesenswert?

Python-Rookie schrieb:
> dass das so umständlich ist mit Parametern
> eingeben...
Was genau findest du daran umständlich?
Es ist genauso "umständlich" wie in C/C++.

Python-Rookie schrieb:
> Bei C++ macht man das ja mit cin...
Das ist was völlig anderes, und das geht auch in Python anders.
https://docs.python.org/3.5/library/functions.html#input
1
#!/usr/bin/env python3
2
3
def fakultaetberechnen(zahl):
4
    ...
5
6
if __name__ == '__main__':
7
    arg = int(input('Bitte Zahl fue Fakultaetsberechung eingeben: '))
8
    fakultaetberechnen(arg)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.