Debug-Ausgabe (was: getopt: Option hat kein oder ein Argument)
[X-Post & F'up2 de.comp.lang.python] Sieghard Schicktanz wrote:
Hallo Bernd,
Du schriebst am Wed, 17 Dec 2014 13:17:19 +0100:
Lies und beherzige bitte <http://einklich.net/usenet/zitier>.
Ist es und tut es aber. Ich benutze z.B. gerne für "transiente" Ausgaben (für Tests und zum Prüfen) vollständig ausgerückte Ausgabe-Statements (die also ab Spalte 1 stehen). Das fällt bei einem einigermaßen ... _Geht_ in Python _nicht_.
debug = True
if debug: statement1 statement2
Ok, und jetzt nochmal in einem "if" innerhalb einer dreifach geschachtelten Schleife, bitte. BTW, in einer Funktion, natürlich.
<https://en.wikipedia.org/wiki/Moving_the_goalposts> Abgesehen davon: In Python schreibt man das IMHO nicht so, sondern geht davon aus, dass Funktionen vom Compiler inlined und unnötige Aufrufe wegoptimiert werden können. Diesen Ansatz empfehle ich auch für andere Programmiersprachen – optimal natürlich als Präprozessor-Makro. Daher stellt sich das Problem erst gar nicht: from sys import stderr debug_level=2 def dmsg (*args, **kwargs): if getattr(kwargs, 'min_level', None) is None: kwargs['min_level'] = 1 if not hasattr(kwargs, 'file'): kwargs['file'] = stderr if debug_level >= kwargs['min_level']: del kwargs['min_level'] print(*args, **kwargs) for …: for …: for …: dmsg("foo", min_level=1) Abgesehen davon: Wer in seinem Code eine dreifach verschachtelte Schleife *direkt* stehen hat, macht sehr wahrscheinlich etwas fhcsla. Denn er hat es wahrscheinlich versäumt, seinen Code mittels Subroutinen (in Python und Shell: Funktionen; in Python zusätzlich: Methoden) zu strukturieren. -- PointedEars Twitter: @PointedEars2 Please do not cc me. / Bitte keine Kopien per E-Mail.
Hallo Thomas, On 2014-12-20 21:52, Thomas 'PointedEars' Lahn wrote:
[X-Post & F'up2 de.comp.lang.python]
Mir fehlt in diesem Posting relativ viel vom Kontext, deshalb kann es sein, dass ich auf Sachen eingehe, die schon erledigt sind.
Du schriebst am Wed, 17 Dec 2014 13:17:19 +0100:
Lies und beherzige bitte <http://einklich.net/usenet/zitier>.
Auf welchen der Punkte dort beziehst du dich in diesem Kontext? :)
Ist es und tut es aber. Ich benutze z.B. gerne für "transiente" Ausgaben (für Tests und zum Prüfen) vollständig ausgerückte Ausgabe-Statements (die also ab Spalte 1 stehen). Das fällt bei einem einigermaßen ... _Geht_ in Python _nicht_.
debug = True
if debug: statement1 statement2
Also, das geht in Python schon und ich finde es, je nachdem, was man untersucht, auch in Ordnung.
Ok, und jetzt nochmal in einem "if" innerhalb einer dreifach geschachtelten Schleife, bitte. BTW, in einer Funktion, natürlich.
<https://en.wikipedia.org/wiki/Moving_the_goalposts>
Abgesehen davon:
In Python schreibt man das IMHO nicht so, sondern geht davon aus, dass Funktionen vom Compiler inlined und unnötige Aufrufe wegoptimiert werden können.
Zumindest in CPython, also der meistverwendeten Implementierung, wird nur extrem wenig "wegoptimiert". (Zum Teil liegt das auch daran, dass sich in Python noch sehr viel zur Laufzeit verändern lässt. Ich will hier nicht abschweifen; bei Interesse kann ich mehr dazu schreiben.) Aber selbst wenn der Compiler mehr machen würde/könnte, würde ich eher davon abraten, Optimierungsempfehlungen an einzelnen Code-Schnipseln festzumachen. Auch darauf kann ich bei Interesse ausführlicher eingehen. :)
Diesen Ansatz empfehle ich auch für andere Programmiersprachen – optimal natürlich als Präprozessor-Makro. Daher stellt sich das Problem erst gar nicht:
from sys import stderr
debug_level=2
def dmsg (*args, **kwargs): if getattr(kwargs, 'min_level', None) is None:
Da `kwargs` ein Mapping ist, meintest du wahrscheinlich if kwargs.pop('min_level', None) is None:
kwargs['min_level'] = 1
Zusammengefasst, also inklusive des `if`, könnte man das übrigens auch als kwargs.setdefault('min_level', 1) schreiben. :-) An sich würde ich aber gar nicht `kwargs` modifizieren, sondern den Wert herausziehen: min_level = kwargs.pop('min_level', 1) und dann `min_level` weiterverwenden. Dann brauchst du weiter unten auch das `del` nicht.
if not hasattr(kwargs, 'file'): kwargs['file'] = stderr
if debug_level >= kwargs['min_level']: del kwargs['min_level'] print(*args, **kwargs)
for …: for …: for …: dmsg("foo", min_level=1)
Abgesehen davon: Wer in seinem Code eine dreifach verschachtelte Schleife *direkt* stehen hat, macht sehr wahrscheinlich etwas fhcsla. Denn er hat es wahrscheinlich versäumt, seinen Code mittels Subroutinen (in Python und Shell: Funktionen; in Python zusätzlich: Methoden) zu strukturieren.
Das kommt drauf an. Wenn zum Beispiel in numerischem Code über ein dreidimensionales Array iteriert wird, ist die dreifach verschachtelte Schleife - je nach Kontext - die "natürliche" Vorgehensweise. Ich gebe dir zwar insofern recht, dass eine dreifach verschachtelte Schleife ein "Warnsignal" ("code smell") ist, aber letztlich hängt es von der Verständlichkeit des konkreten Codes ab, ob oder wie man es anders machen sollte. Viele Grüße Stefan
participants (2)
-
Stefan Schwarzer
-
Thomas 'PointedEars' Lahn