您是否曾经使用print()
或log()
来调试代码?当然可以。 IceCream,简称ic
,使打印调试变得更加甜蜜。
ic()
类似于print()
,但更好:
IceCream 经过充分测试,获得许可,并支持 Python 3 和 PyPy3。
IceCream 正在寻找主要贡献者 + 维护者。您愿意领导 IceCream 并为每个人改进 Python 调试吗?请联系我并让我知道! ?
您曾经打印过变量或表达式来调试程序吗?如果你曾经输入过类似的内容
print ( foo ( '123' ))
或者更彻底
print ( "foo('123')" , foo ( '123' ))
然后ic()
会让你脸上露出微笑。对于参数, ic()
检查自身并打印它自己的参数以及这些参数的值。
from icecream import ic
def foo ( i ):
return i + 333
ic ( foo ( 123 ))
印刷
ic| foo(123): 456
相似地,
d = { 'key' : { 1 : 'one' }}
ic ( d [ 'key' ][ 1 ])
class klass ():
attr = 'yep'
ic ( klass . attr )
印刷
ic| d['key'][1]: 'one'
ic| klass.attr: 'yep'
只需给ic()
一个变量或表达式即可。简单的。
您是否曾经使用print()
来确定程序的哪些部分被执行以及它们的执行顺序?例如,如果您曾经添加过 print 语句来调试代码,例如
def foo ():
print ( 0 )
first ()
if expression :
print ( 1 )
second ()
else :
print ( 2 )
third ()
那么ic()
在这里也有帮助。如果没有参数, ic()
会检查自身并打印调用文件名、行号和父函数。
from icecream import ic
def foo ():
ic ()
first ()
if expression :
ic ()
second ()
else :
ic ()
third ()
印刷
ic| example.py:4 in foo()
ic| example.py:11 in foo()
只需调用ic()
即可完成。简单的。
ic()
返回其参数,因此ic()
可以轻松插入到预先存在的代码中。
>>> a = 6
>>> def half ( i ):
>>> return i / 2
>>> b = half(ic(a))
ic| a: 6
>>> ic(b)
ic| b: 3
ic.format(*args)
与ic()
类似,但输出以字符串形式返回,而不是写入 stderr。
>>> from icecream import ic
>>> s = ' sup '
>>> out = ic.format(s)
>>> print (out)
ic| s: 'sup'
此外,可以完全禁用ic()
的输出,然后分别使用ic.disable()
和ic.enable()
重新启用。
from icecream import ic
ic ( 1 )
ic . disable ()
ic ( 2 )
ic . enable ()
ic ( 3 )
印刷
ic| 1: 1
ic| 3: 3
当然, ic()
在禁用时会继续返回其参数;没有ic()
中断的现有代码。
要使ic()
在每个文件中可用而不需要在每个文件中导入,您可以install()
它。例如,在根A.py
中:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from icecream import install
install ()
from B import foo
foo ()
然后在由A.py
导入的B.py
中,只需调用ic()
:
# -*- coding: utf-8 -*-
def foo ():
x = 3
ic ( x )
install()
将ic()
添加到内置模块,该模块在解释器导入的所有文件之间共享。类似地, ic()
也可以稍后被uninstall()
编辑。
如果未安装 IceCream, ic()
也可以以正常失败的方式导入,就像在生产环境中(即不是开发环境)一样。为此,这个后备导入片段可能会很有用:
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)
控制ic()
的输出。
prefix
,如果提供,采用自定义输出前缀。 prefix
可以是字符串,例如
>>> from icecream import ic
>>> ic.configureOutput( prefix = ' hello -> ' )
>>> ic( ' world ' )
hello -> 'world'
或一个函数。
>>> import time
>>> from icecream import ic
>>>
>>> def unixTimestamp ():
>>> return ' %i |> ' % int (time.time())
>>>
>>> ic.configureOutput( prefix = unixTimestamp)
>>> ic( ' world ' )
1519185860 |> 'world': 'world'
prefix
的默认值为ic|
。
如果提供了,则每次ic()
调用都会调用一次outputFunction
,并将ic()
的输出作为字符串,而不是将该字符串写入 stderr (默认)。
>>> import logging
>>> from icecream import ic
>>>
>>> def warn ( s ):
>>> logging.warning(s)
>>>
>>> ic.configureOutput( outputFunction = warn)
>>> ic( ' eep ' )
WARNING:root:ic| 'eep': 'eep'
argToStringFunction
(如果提供)将使用要序列化为可显示字符串的参数值进行调用。默认值是 PrettyPrint 的 pprint.pformat(),但可以更改为例如以自定义方式处理非标准数据类型。
>>> 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!]
默认的argToStringFunction
是icecream.argumentToString
,并且具有register
和unregister
要使用functools.singledispatch
为特定类分派的函数的方法。它还具有一个registry
属性来查看注册的函数。
>>> 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
如果提供且为 True,则将ic()
调用的文件名、行号和父函数添加到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
默认为 False。
contextAbsPath
如果提供且为 True,则当使用includeContext == True
调用ic()
时,输出绝对文件路径(如/path/to/foo.py
,而不是文件名(如foo.py
。这在调试共享相同文件名的多个文件时非常有用。此外,某些编辑器(例如 VSCode)将绝对文件路径转换为可单击的链接,以打开调用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
默认为 False。
使用 pip 安装 IceCream 很简单。
$ pip install icecream
ic()
使用@alexmojaki executing
来可靠地定位 Python 源代码中的ic()
调用。这很神奇。
每种语言都应该享受美味的冰淇淋。
如果您想要使用您最喜欢的语言的类似ic()
函数,请打开拉取请求! IceCream 的目标是在每种语言中使用方便的ic()
函数来简化打印调试。