OptionParser problem

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Hi.
Ich verwende OptionParser und wenn der User keine Parameter übergibt dann soll eine Anleitung angezeigt werden:

Code: Alles auswählen

#!/usr/bin/env python
import sys
from optparse import OptionParser

if __name__ == '__main__':
    parser = OptionParser("Usage: %prog -f FileName [Option]")

    parser.add_option("-f", "--file", type="string", dest="FileName",
        help="File name.")

    (opts, args) = parser.parse_args()

    print len(args)
    
    if len(args) > 0:
        parser.print_help()
        sys.exit(1)
Wenn ich python xxxx.py -f hallo.txt verwende ist die variable args weiterhin 0 und nicht 1. Wie kann ich dies beheben?

Viele Grüße
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Das Leben ist wie ein Tennisball.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

mit hat geschrieben:Ich verwende OptionParser und wenn der User keine Parameter übergibt dann soll eine Anleitung angezeigt werden:
Das ist ziemlich unüblich: Wenn es keine Parameter gibt, sollte das Programm einfach laufen. Mit -h oder --help wird dann der usage-String angezeigt und eine Zusammenfassung der Optionen angezeigt -- siehe Link von EyDu.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

CM hat geschrieben:
mit hat geschrieben:Ich verwende OptionParser und wenn der User keine Parameter übergibt dann soll eine Anleitung angezeigt werden:
Das ist ziemlich unüblich: Wenn es keine Parameter gibt, sollte das Programm einfach laufen. Mit -h oder --help wird dann der usage-String angezeigt und eine Zusammenfassung der Optionen angezeigt -- siehe Link von EyDu.
Nuja, wenn das Programm ohne Parameter nichts tun kann, dann ist es schon üblich zumindest eine Ausgabe zu geben, in der auf die Hilfeseite mit dem Schalter -h / --help hingewiesen wird.

Aber das kann man ja leicht prüfen und entsprechend verzweigen. (len() von opts und args)

@mit: EyDu hat Dir ja schon den Wink mit dem Zaunpfhal gegeben. Ich schlage noch mal folgendes vor:

Code: Alles auswählen

print "opts", opts
print "args", args
Das hätte diesen Thread mit einiger sicherheit obsolet gemacht :-D
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Lots of people want their programs to have “required options”. Think about it. If it’s required, then it’s not optional! If there is a piece of information that your program absolutely requires in order to run successfully, that’s what positional arguments are for.
Deswegen schrieb ich "unüblich". Klar hält einen niemand davon ab, doch sind IMHO "arguments" bzw. "positional arguments" einer "required option" vorzuziehen. Programme / Skripte, die ein halbes Jahr später noch intuitiv zu benutzen sind, geben gute defaults und zeigen eine Hilfe an, wenn benötigte Argumente (nicht Optionen) fehlen. Wenn über optparse die Hilfe ausgegeben wird, wird automatisch auf -h/--help hingewiesen.

Just my $.02 .
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

CM hat geschrieben:
Lots of people want their programs to have “required options”. Think about it. If it’s required, then it’s not optional! If there is a piece of information that your program absolutely requires in order to run successfully, that’s what positional arguments are for.
Deswegen schrieb ich "unüblich". Klar hält einen niemand davon ab, doch sind IMHO "arguments" bzw. "positional arguments" einer "required option" vorzuziehen. Programme / Skripte, die ein halbes Jahr später noch intuitiv zu benutzen sind, geben gute defaults und zeigen eine Hilfe an, wenn benötigte Argumente (nicht Optionen) fehlen.
Hm.. da muss ich mich noch mal schlau lesen bezüglich der Terminologie. Ich vermute mal wir denken da schon an das gleiche.
Wenn über optparse die Hilfe ausgegeben wird, wird automatisch auf -h/--help hingewiesen.
Sicher. Aber das ist ja kein Mehrwert an der Stelle. Wenn ich die Hilfe aufgerufen habe, dann kenne ich den Parameter "-h" ja schon ;-)

Sinnvoll ist es darauf hinzuweisen, wenn ich eben etwas angeben muss! Dann will ich ja nicht gleich die gesamte Hilfe lesen, sondern speziell darauf hingewiesen werden, dass "etwas" fehlt und dass ich mir doch mal die Hilfe angucken sollte, die man wiederum so und so erreichen kann.

Mal meine 4 Pfennig :-)
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Sinnvoll ist es darauf hinzuweisen, wenn ich eben etwas angeben muss! Dann will ich ja nicht gleich die gesamte Hilfe lesen, sondern speziell darauf hingewiesen werden, dass "etwas" fehlt und dass ich mir doch mal die Hilfe angucken sollte, die man wiederum so und so erreichen kann.
Das würde mir auch gefallen, aber wie kann ich den oberen vorschlag implementieren, denn len(opts) und len(args) funtioniert nicht?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

mit hat geschrieben: Das würde mir auch gefallen, aber wie kann ich den oberen vorschlag implementieren, denn len(opts) und len(args) funtioniert nicht?
Ist das eine Frage? Wenn ja, probiere es doch aus! Wenn nein, wie äußert sich denn "funktioniert" nicht?
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Wenn ich es ausprobiere bekomme ich diese Fehlermeldung:

Code: Alles auswählen

$ python2.5 test1.py -f sdlfjs
opts {'FileName': 'sdlfjs'}
Traceback (most recent call last):
  File "test1.py", line 13, in <module>
    print "opts", opts, len(opts)
AttributeError: Values instance has no attribute '__len__'

Code: Alles auswählen

#!/usr/bin/env python
import sys
from optparse import OptionParser

if __name__ == '__main__':
    parser = OptionParser("Usage: %prog -f FileName [Option]")

    parser.add_option("-f", "--file", type="string", dest="FileName",
        help="File name.")

    (opts, args) = parser.parse_args()

    print "opts", opts, len(opts) 
    print "args", args, len(args)
Was mache ich falsch?
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

opts ist kein Dict, sondern eine Instanz der Klasse Values, für die len nicht implementiert ist.
Falls Du die Anzahl wirklich brauchst:

Code: Alles auswählen

len(opts.__dict__)
MfG
HWK
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke, aber es hilft mir nicht weiter (len(opts.__dict__)) denn wenn ich kein Parameter übergebe ist es 1 und wenn ich ein Parameter übergebe ist auch 1

Code: Alles auswählen

$ python2.5 test1.py
opts {'FileName': None}
args []
1
$ python2.5 test1.py -f kdfs
opts {'FileName': 'kdfs'}
args []
1
Was mache ich falsch?
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Dann prüf doch einfach ob FileName gleich None ist

Code: Alles auswählen

opts['FileName'] == None
the more they change the more they stay the same
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Auf ``None`` kann und sollte man mit ``is`` testen.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke, aber nun bekomme ich diese Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "test1.py", line 18, in <module>
    if opts['FileName'] == None:
AttributeError: Values instance has no attribute '__getitem__'
Was mache ich falsch?
Zuletzt geändert von mit am Sonntag 6. Dezember 2009, 13:20, insgesamt 1-mal geändert.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

versuchs mal mit:

Code: Alles auswählen

opts.__dict__['FileName'] is None
the more they change the more they stay the same
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke es funktioniert.
lunar

Dav1d hat geschrieben:versuchs mal mit:

Code: Alles auswählen

opts.__dict__['FileName'] is None
Da kann man auch gleich "opts.FileName is None" schreiben.
BlackJack

Das kann man nicht nur, das *sollte* man auch. `__dict__` ist ein Implementierungsdetail, das muss nicht vorhanden sein.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke es funktioniert.
Antworten