Verwenden Sie jemals print()
oder log()
um Ihren Code zu debuggen? Natürlich tust du das. IceCream, kurz ic
, macht das Drucken-Debuggen ein wenig angenehmer.
ic()
ist wie print()
, aber besser:
IceCream ist gut getestet, freizügig lizenziert und unterstützt Python 3 und PyPy3.
IceCream sucht einen Hauptmitwirkenden + Betreuer. Würden Sie gerne IceCream leiten und das Debuggen für alle in Python verbessern? Bitte melden Sie sich bei mir und lassen Sie es mich wissen! ?
Haben Sie schon einmal Variablen oder Ausdrücke gedruckt, um Ihr Programm zu debuggen? Wenn Sie jemals so etwas eingegeben haben wie
print ( foo ( '123' ))
oder desto gründlicher
print ( "foo('123')" , foo ( '123' ))
dann zaubert ic()
ein Lächeln auf Ihr Gesicht. Mit Argumenten überprüft sich ic()
selbst und gibt sowohl seine eigenen Argumente als auch die Werte dieser Argumente aus.
from icecream import ic
def foo ( i ):
return i + 333
ic ( foo ( 123 ))
Drucke
ic| foo(123): 456
Ähnlich,
d = { 'key' : { 1 : 'one' }}
ic ( d [ 'key' ][ 1 ])
class klass ():
attr = 'yep'
ic ( klass . attr )
Drucke
ic| d['key'][1]: 'one'
ic| klass.attr: 'yep'
Geben Sie ic()
einfach eine Variable oder einen Ausdruck und schon sind Sie fertig. Einfach.
Haben Sie jemals print()
verwendet, um zu bestimmen, welche Teile Ihres Programms ausgeführt werden und in welcher Reihenfolge sie ausgeführt werden? Wenn Sie beispielsweise schon einmal print-Anweisungen zum Debuggen von Code hinzugefügt haben, z. B
def foo ():
print ( 0 )
first ()
if expression :
print ( 1 )
second ()
else :
print ( 2 )
third ()
dann hilft ic()
auch hier. Ohne Argumente überprüft sich ic()
selbst und gibt den Namen der aufrufenden Datei, die Zeilennummer und die übergeordnete Funktion aus.
from icecream import ic
def foo ():
ic ()
first ()
if expression :
ic ()
second ()
else :
ic ()
third ()
Drucke
ic| example.py:4 in foo()
ic| example.py:11 in foo()
Rufen Sie einfach ic()
auf und schon sind Sie fertig. Einfach.
ic()
gibt seine Argumente zurück, sodass ic()
problemlos in bereits vorhandenen Code eingefügt werden kann.
>>> a = 6
>>> def half ( i ):
>>> return i / 2
>>> b = half(ic(a))
ic| a: 6
>>> ic(b)
ic| b: 3
ic.format(*args)
ist wie ic()
, aber die Ausgabe wird als String zurückgegeben und nicht in stderr geschrieben.
>>> from icecream import ic
>>> s = ' sup '
>>> out = ic.format(s)
>>> print (out)
ic| s: 'sup'
Darüber hinaus kann die Ausgabe von ic()
mit ic.disable()
bzw. ic.enable()
vollständig deaktiviert und später wieder aktiviert werden.
from icecream import ic
ic ( 1 )
ic . disable ()
ic ( 2 )
ic . enable ()
ic ( 3 )
Drucke
ic| 1: 1
ic| 3: 3
ic()
gibt seine Argumente natürlich weiterhin zurück, wenn es deaktiviert ist; Kein vorhandener Code mit ic()
-Breaks.
Um ic()
in jeder Datei verfügbar zu machen, ohne in jede Datei importiert werden zu müssen, können Sie es install()
. Zum Beispiel in einem A.py
:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from icecream import install
install ()
from B import foo
foo ()
und dann rufen Sie in B.py
, das von A.py
importiert wird, einfach ic()
auf:
# -*- coding: utf-8 -*-
def foo ():
x = 3
ic ( x )
install()
fügt ic()
zum Builtins-Modul hinzu, das von allen vom Interpreter importierten Dateien gemeinsam genutzt wird. Ebenso kann ic()
später auch uninstall()
bearbeitet werden.
ic()
kann auch auf eine Weise importiert werden, die ordnungsgemäß fehlschlägt, wenn IceCream nicht installiert ist, wie in Produktionsumgebungen (dh nicht in der Entwicklung). Zu diesem Zweck könnte sich dieses Fallback-Import-Snippet als nützlich erweisen:
try :
from icecream import ic
except ImportError : # Graceful fallback if IceCream isn't installed.
ic = lambda * a : None if not a else ( a [ 0 ] if len ( a ) == 1 else a ) # noqa
ic.configureOutput(prefix, outputFunction, argToStringFunction, includeContext, contextAbsPath)
steuert die Ausgabe von ic()
.
prefix
übernimmt, sofern angegeben, ein benutzerdefiniertes Ausgabepräfix. prefix
kann eine Zeichenfolge sein, z
>>> from icecream import ic
>>> ic.configureOutput( prefix = ' hello -> ' )
>>> ic( ' world ' )
hello -> 'world'
oder eine Funktion.
>>> import time
>>> from icecream import ic
>>>
>>> def unixTimestamp ():
>>> return ' %i |> ' % int (time.time())
>>>
>>> ic.configureOutput( prefix = unixTimestamp)
>>> ic( ' world ' )
1519185860 |> 'world': 'world'
Der Standardwert von prefix
ist ic|
.
outputFunction
wird, sofern angegeben, bei jedem ic()
Aufruf einmal aufgerufen, wobei die Ausgabe von ic()
als Zeichenfolge erfolgt, anstatt dass diese Zeichenfolge in stderr geschrieben wird (Standardeinstellung).
>>> import logging
>>> from icecream import ic
>>>
>>> def warn ( s ):
>>> logging.warning(s)
>>>
>>> ic.configureOutput( outputFunction = warn)
>>> ic( ' eep ' )
WARNING:root:ic| 'eep': 'eep'
argToStringFunction
wird, falls angegeben, mit Argumentwerten aufgerufen, die in anzeigbare Zeichenfolgen serialisiert werden sollen. Der Standardwert ist pprint.pformat() von PrettyPrint, dies kann jedoch geändert werden, um beispielsweise nicht standardmäßige Datentypen auf benutzerdefinierte Weise zu verarbeiten.
>>> from icecream import ic
>>>
>>> def toString ( obj ):
>>> if isinstance (obj, str ):
>>> return ' [!string %r with length %i !] ' % (obj, len (obj))
>>> return repr (obj)
>>>
>>> ic.configureOutput( argToStringFunction = toString)
>>> ic( 7 , ' hello ' )
ic| 7: 7, 'hello': [!string 'hello' with length 5!]
Die standardmäßige argToStringFunction
ist icecream.argumentToString
und verfügt über Methoden zum register
und unregister
von Funktionen, die für bestimmte Klassen mithilfe von functools.singledispatch
gesendet werden sollen. Es verfügt außerdem über eine registry
zum Anzeigen registrierter Funktionen.
>>> from icecream import ic, argumentToString
>>> import numpy as np
>>>
>>> # Register a function to summarize numpy array
>>> @ argumentToString.register(np.ndarray)
>>> def _ ( obj ):
>>> return f " ndarray, shape= { obj.shape } , dtype= { obj.dtype } "
>>>
>>> x = np.zeros(( 1 , 2 ))
>>> ic(x)
ic| x: ndarray, shape=(1, 2), dtype=float64
>>>
>>> # View registered functions
>>> argumentToString.registry
mappingproxy({object: <function icecream.icecream.argumentToString(obj)>,
numpy.ndarray: <function __main__._(obj)>})
>>>
>>> # Unregister a function and fallback to the default behavior
>>> argumentToString.unregister(np.ndarray)
>>> ic(x)
ic| x: array([[0., 0.]])
includeContext
fügt, falls angegeben und True, den Dateinamen, die Zeilennummer und die übergeordnete Funktion des ic( ic()
Aufrufs zur Ausgabe von ic()
hinzu.
>>> from icecream import ic
>>> ic.configureOutput( includeContext = True )
>>>
>>> def foo ():
>>> i = 3
>>> ic(i)
>>> foo()
ic| example.py:12 in foo()- i: 3
includeContext
ist standardmäßig False.
contextAbsPath
gibt, wenn angegeben und True, absolute Dateipfade aus, wie /path/to/foo.py
, über nur Dateinamen, wie foo.py
, wenn ic()
mit includeContext == True
aufgerufen wird. Dies ist nützlich, wenn Sie mehrere Dateien debuggen, die denselben Dateinamen haben. Darüber hinaus wandeln einige Editoren wie VSCode absolute Dateipfade in anklickbare Links um, die die Datei öffnen, in der ic()
aufgerufen wurde.
>>> from icecream import ic
>>> ic.configureOutput( includeContext = True , contextAbsPath = True )
>>>
>>> i = 3
>>>
>>> def foo ():
>>> ic(i)
>>> foo()
ic| /absolute/path/to/example.py:12 in foo()- i: 3
>>>
>>> ic.configureOutput( includeContext = True , contextAbsPath = False )
>>>
>>> def foo ():
>>> ic(i)
>>> foo()
ic| example.py:18 in foo()- i: 3
contextAbsPath
ist standardmäßig False.
Die Installation von IceCream mit pip ist einfach.
$ pip install icecream
ic()
nutzt executing
durch @alexmojaki, um ic()
-Aufrufe in der Python-Quelle zuverlässig zu lokalisieren. Es ist Magie.
Leckeres Eis sollte in jeder Sprache genossen werden.
Wenn Sie eine ähnliche ic()
Funktion in Ihrer Lieblingssprache wünschen, öffnen Sie bitte eine Pull-Anfrage! Das Ziel von IceCream ist es, das Drucken-Debuggen mit einer praktischen ic()
Funktion in jeder Sprache zu vereinfachen.