Ich kenne das --verbose
oder -v
von mehreren Tools und möchte dies in einige meiner eigenen Skripte und Tools implementieren.
Ich dachte an die Platzierung:
if verbose:
print ...
Wenn ein Benutzer die -v
Option übergibt , wird die Variable verbose
auf gesetzt True
und der Text gedruckt.
Ist dies der richtige Ansatz oder gibt es einen allgemeineren Weg?
Ergänzung: Ich frage nicht nach einer Möglichkeit, das Parsen von Argumenten zu implementieren. Dass ich weiß, wie es gemacht wird. Ich interessiere mich nur speziell für die ausführliche Option.
Antworten:
Mein Vorschlag ist, eine Funktion zu verwenden. Aber anstatt das
if
in die Funktion zu setzen, zu der Sie möglicherweise versucht sind, gehen Sie folgendermaßen vor:(Ja, Sie können eine Funktion in einer
if
Anweisung definieren, die nur definiert wird, wenn die Bedingung erfüllt ist!)Wenn Sie Python 3 verwenden, wo
print
bereits eine Funktion vorhanden ist (oder wenn Sie bereit sind, sieprint
in 2.x als Funktion zu verwendenfrom __future__ import print_function
), ist dies noch einfacher:Auf diese Weise wird die Funktion als Nichtstun definiert, wenn der ausführliche Modus deaktiviert ist (mit einem Lambda), anstatt das
verbose
Flag ständig zu testen .Wenn der Benutzer den Ausführlichkeitsmodus während der Ausführung Ihres Programms ändern könnte , wäre dies der falsche Ansatz (Sie benötigen den
if
in der Funktion), aber da Sie ihn mit einem Befehlszeilenflag setzen, müssen Sie nur Treffen Sie die Entscheidung einmal.Sie verwenden dann zB
verboseprint("look at all my verbosity!", object(), 3)
immer dann, wenn Sie eine "ausführliche" Nachricht drucken möchten.quelle
print
Funktion: Akzeptieren Sie viele Argumente. Es kann wieprint(*args)
in 3.x und wiefor arg in args: print arg,
in 2.x implementiert werden . Der Hauptvorteil besteht darin, dass Zeichenfolgen und andere Typen in einer Nachricht ohne explizitestr
Aufrufe / Formatierungen und Verkettungen gemischt werden können.print arg,
Zeile verwendet?def verboseprint(*args, **kwargs): print(*args, **kwargs)
Verwenden Sie das
logging
Modul:Alle diese gehen automatisch zu
stderr
:Weitere Informationen finden Sie in den Python-Dokumenten und in den Tutorials .
quelle
Um die Antwort von @ kindall zu erstellen und zu vereinfachen, verwende ich normalerweise Folgendes:
Dies bietet dann die folgende Verwendung in Ihrem Skript:
Und Ihr Skript kann folgendermaßen aufgerufen werden:
Ein paar Anmerkungen:
3
, die die Obergrenze für Ihre Protokollierung festlegt, aber ich akzeptiere dies der Einfachheit halber als Kompromiss.v_print
während Ihres gesamten Programms arbeiten möchten , müssen Sie den Müll mit dem globalen erledigen. Es macht keinen Spaß, aber ich fordere jemanden auf, einen besseren Weg zu finden.quelle
-v
es verwendet wird. In Ihrer aktuellen Lösung wird alles auf stdout anstatt auf stderr ausgegeben. Und: Normalerweise möchten Sie jeden Fehler an den Benutzer weiterleiten, nicht wahr?In meinen Skripten überprüfe ich zur Laufzeit, ob die Option "Ausführlich" aktiviert ist, und setze dann meine Protokollierungsstufe auf "Debuggen". Wenn es nicht eingestellt ist, setze ich es auf info. Auf diese Weise müssen Sie Ihren gesamten Code nicht "wenn ausführlich" überprüfen.
quelle
Es könnte sauberer sein, wenn Sie eine Funktion haben, beispielsweise aufgerufen
vprint
, die das ausführliche Flag für Sie überprüft. Dann rufen Sie einfach Ihre eigenevprint
Funktion an einer beliebigen Stelle auf, an der Sie eine optionale Ausführlichkeit wünschen.quelle
Ich habe den Protokollierungscode von virtualenv für ein Projekt von mir gestohlen . Schauen Sie in nach,
main()
umvirtualenv.py
zu sehen, wie es initialisiert wird. Der Code ist bestreut mitlogger.notify()
,logger.info()
,logger.warn()
und dergleichen. Welche Methoden tatsächlich Emit Ausgang dadurch bestimmt wird , ob mit virtualenv aufgerufen wurde-v
,-vv
,-vvv
, oder-q
.quelle
Die Lösung von @ kindall funktioniert nicht mit meiner Python-Version 3.5. @styles gibt in seinem Kommentar korrekt an, dass der Grund das zusätzliche optionale Schlüsselwortargument ist . Daher sieht meine leicht verfeinerte Version für Python 3 folgendermaßen aus:
quelle
Es könnte eine globale Variable geben, die wahrscheinlich mit
argparse
from gesetzt istsys.argv
und dafür steht, ob das Programm ausführlich sein soll oder nicht. Dann könnte ein Dekorateur so geschrieben werden, dass bei aktivierter Ausführlichkeit die Standardeingabe in das Nullgerät umgeleitet wird, solange die Funktion ausgeführt wird:Diese Antwort ist von diesem Code inspiriert . Eigentlich wollte ich es nur als Modul in meinem Programm verwenden, aber ich bekam Fehler, die ich nicht verstehen konnte, also habe ich einen Teil davon angepasst.
Der Nachteil dieser Lösung ist, dass die Ausführlichkeit im Gegensatz zu binär ist
logging
, was eine genauere Abstimmung der Ausführlichkeit des Programms ermöglicht. Außerdem werden alleprint
Anrufe umgeleitet, was möglicherweise unerwünscht ist.quelle
Was ich brauche, ist eine Funktion, die ein Objekt (obj) druckt, aber nur wenn die globale Variable verbose wahr ist, sonst tut sie nichts.
Ich möchte den globalen Parameter "verbose" jederzeit ändern können. Einfachheit und Lesbarkeit sind für mich von größter Bedeutung. Ich würde also wie folgt vorgehen:
Die globale Variable "verbose" kann auch aus der Parameterliste eingestellt werden.
quelle