¿Alguna vez usaste print()
o log()
para depurar tu código? Por supuesto que sí. IceCream, o ic
para abreviar, hace que la depuración de impresiones sea un poco más sencilla.
ic()
es como print()
, pero mejor:
IceCream está bien probado, tiene licencia permisiva y es compatible con Python 3 y PyPy3.
IceCream está buscando un colaborador principal + mantenedor. ¿Le encantaría liderar IceCream y mejorar la depuración para todos en Python? ¡Comuníquese y hágamelo saber! ?
¿Alguna vez ha impreso variables o expresiones para depurar su programa? Si alguna vez has escrito algo como
print ( foo ( '123' ))
o el más completo
print ( "foo('123')" , foo ( '123' ))
entonces ic()
te hará sonreír. Con los argumentos, ic()
se inspecciona a sí mismo e imprime tanto sus propios argumentos como los valores de esos argumentos.
from icecream import ic
def foo ( i ):
return i + 333
ic ( foo ( 123 ))
Huellas dactilares
ic| foo(123): 456
Similarmente,
d = { 'key' : { 1 : 'one' }}
ic ( d [ 'key' ][ 1 ])
class klass ():
attr = 'yep'
ic ( klass . attr )
Huellas dactilares
ic| d['key'][1]: 'one'
ic| klass.attr: 'yep'
Simplemente dale ic()
una variable o expresión y listo. Fácil.
¿Alguna vez ha utilizado print()
para determinar qué partes de su programa se ejecutan y en qué orden se ejecutan? Por ejemplo, si alguna vez agregó declaraciones impresas al código de depuración como
def foo ():
print ( 0 )
first ()
if expression :
print ( 1 )
second ()
else :
print ( 2 )
third ()
entonces ic()
también ayuda aquí. Sin argumentos, ic()
se inspecciona a sí mismo e imprime el nombre del archivo que llama, el número de línea y la función principal.
from icecream import ic
def foo ():
ic ()
first ()
if expression :
ic ()
second ()
else :
ic ()
third ()
Huellas dactilares
ic| example.py:4 in foo()
ic| example.py:11 in foo()
Simplemente llame ic()
y listo. Simple.
ic()
devuelve su(s) argumento(s), por lo que ic()
puede insertarse fácilmente en código preexistente.
>>> a = 6
>>> def half ( i ):
>>> return i / 2
>>> b = half(ic(a))
ic| a: 6
>>> ic(b)
ic| b: 3
ic.format(*args)
es como ic()
pero la salida se devuelve como una cadena en lugar de escribirse en stderr.
>>> from icecream import ic
>>> s = ' sup '
>>> out = ic.format(s)
>>> print (out)
ic| s: 'sup'
Además, la salida de ic()
se puede deshabilitar por completo y luego volver a habilitarla con ic.disable()
y ic.enable()
respectivamente.
from icecream import ic
ic ( 1 )
ic . disable ()
ic ( 2 )
ic . enable ()
ic ( 3 )
Huellas dactilares
ic| 1: 1
ic| 3: 3
ic()
continúa devolviendo sus argumentos cuando está deshabilitado, por supuesto; no existe ningún código con interrupciones ic()
.
Para que ic()
esté disponible en cada archivo sin necesidad de importarlo en cada archivo, puede install()
. Por ejemplo, en una raíz A.py
:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from icecream import install
install ()
from B import foo
foo ()
y luego en B.py
, que es importado por A.py
, simplemente llame ic()
:
# -*- coding: utf-8 -*-
def foo ():
x = 3
ic ( x )
install()
agrega ic()
al módulo integrado, que se comparte entre todos los archivos importados por el intérprete. De manera similar, ic()
también se puede editar más tarde con uninstall()
.
ic()
también se puede importar de una manera que falle correctamente si IceCream no está instalado, como en entornos de producción (es decir, no de desarrollo). Con ese fin, este fragmento de importación alternativo puede resultar útil:
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)
controla la salida de ic()
.
prefix
, si se proporciona, adopta un prefijo de salida personalizado. prefix
puede ser una cadena, como
>>> from icecream import ic
>>> ic.configureOutput( prefix = ' hello -> ' )
>>> ic( ' world ' )
hello -> 'world'
o una función.
>>> import time
>>> from icecream import ic
>>>
>>> def unixTimestamp ():
>>> return ' %i |> ' % int (time.time())
>>>
>>> ic.configureOutput( prefix = unixTimestamp)
>>> ic( ' world ' )
1519185860 |> 'world': 'world'
El valor predeterminado del prefix
es ic|
.
outputFunction
, si se proporciona, se llama una vez por cada llamada a ic ic()
con la salida de ic()
, como una cadena, en lugar de que esa cadena se escriba en stderr (el valor predeterminado).
>>> import logging
>>> from icecream import ic
>>>
>>> def warn ( s ):
>>> logging.warning(s)
>>>
>>> ic.configureOutput( outputFunction = warn)
>>> ic( ' eep ' )
WARNING:root:ic| 'eep': 'eep'
argToStringFunction
, si se proporciona, se llama con valores de argumento que se serializarán en cadenas visualizables. El valor predeterminado es pprint.pformat() de PrettyPrint, pero esto se puede cambiar para, por ejemplo, manejar tipos de datos no estándar de forma personalizada.
>>> 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!]
La argToStringFunction
predeterminada es icecream.argumentToString
y tiene métodos para register
y unregister
de funciones que se enviarán a clases específicas mediante functools.singledispatch
. También cuenta con una propiedad registry
para visualizar funciones registradas.
>>> 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
, si se proporciona y es True, agrega el nombre de archivo, el número de línea y la función principal de la llamada ic()
a la salida de ic()
.
>>> from icecream import ic
>>> ic.configureOutput( includeContext = True )
>>>
>>> def foo ():
>>> i = 3
>>> ic(i)
>>> foo()
ic| example.py:12 in foo()- i: 3
includeContext
es Falso de forma predeterminada.
contextAbsPath
, si se proporciona y es True, genera rutas de archivos absolutas, como /path/to/foo.py
, sobre solo nombres de archivos, como foo.py
, cuando se llama ic()
con includeContext == True
. Esto es útil al depurar varios archivos que comparten los mismos nombres de archivo. Además, algunos editores, como VSCode, convierten las rutas de archivo absolutas en enlaces en los que se puede hacer clic y que abren el archivo donde se llamó ic()
.
>>> 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
es Falso de forma predeterminada.
Instalar IceCream con pip es fácil.
$ pip install icecream
ic()
utiliza executing
de @alexmojaki para localizar de manera confiable las llamadas ic()
en el código fuente de Python. Es mágico.
Se debe disfrutar un delicioso helado en todos los idiomas.
Si desea una función ic()
similar en su idioma favorito, abra una solicitud de extracción. El objetivo de IceCream es mejorar la depuración de impresiones con una útil función ic()
en todos los idiomas.