icecream - 切勿使用print()再次调试
您是否曾经使用print()或log()调试代码?当然,您会这样做。 icecream或简称IC,使打印调试更甜蜜。
ic()就像print(),但更好:
- 它打印了变量和表达式及其值。
- 输入快60%。
- 数据结构是格式的,并打印出了漂亮的印刷。
- 输出突出显示。
- 它选择包括程序上下文:文件名,行号和父函数。
icecream经过良好的测试,允许的许可并支持Python 3和PYPY3。
2025-04-26:Big Scoop:我很高兴分享@Jakeroid现在是icecream的维护者! ? icecream的未来刚好甜美。 ?
检查变量
您是否曾经打印过变量或表达方式来调试程序?如果您曾经输入过类似的内容
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()来确定程序的哪些部分执行,以及执行的顺序?例如,如果您曾经在调试代码中添加打印语句
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()可用,而无需在每个文件中导入,则可以安装()。例如,在root 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()稍后也可以卸载()ed。
如果未安装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(前缀,输出函数,argtoStringFunction,includeContext,contextAbspath)控制IC()的输出。
前缀(如果提供)采用自定义输出前缀。前缀可以是字符串,例如
>>> 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'前缀的默认值是IC | 。
输出功能(如果提供),则以IC()的输出为字符串,而不是写入stderr(默认值)的每个IC()呼叫一次。
>>> import logging
>>> from icecream import ic
>>>
>>> def warn ( s ):
>>> logging.warning( " %s " , 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,并且具有使用Functool.SingledIsPatch派遣和未注册的函数进行注册和未注册函数。它还具有注册属性以查看注册功能。
>>> 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(如果提供),并且将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是错误的。
contextabspath(如果提供且真实),则输出绝对的filepath,例如/path/path/foo.py,在诸如foo.py之类的fileAnames上,当inc(Incl.ycontext == true)调用ic(iC())时。当调试共享相同文件名的多个文件时,这很有用。此外,某些编辑器(例如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是错误的。
如果要使用多个日志级别的icecream ,例如使用Python的日志记录模块,则可以使用ic.format()将icecream的调试与Logger集成:
import logging
from icecream import ic
foo = 'bar'
logging . debug ( ic . format ( foo ))❕这有点笨拙。您是否更喜欢icecream中的内置日志级别支持?如果是这样,请分享您的想法。
安装
使用PIP安装icecream很容易。
$ pip install icecream
相关的Python库
IC()使用@AlexMoJaki执行,可在Python源中可靠地找到IC()调用。这是魔术。
其他语言的icecream
每种语言都应享受美味的icecream 。
- 飞镖: icecream
- 锈: icecream -rs
- node.js:node- icecream
- C ++: icecream -CPP
- C99: icecream -C
- PHP: icecream -PHP
- 去: icecream -Go
- Ruby:r icecream
- Java: icecream -Java
- R: icecream
- lua: icecream -Lua
- clojure(脚本): icecream -cljc
- bash: icecream -bash
- SystemVerilog: icecream _SV
如果您想要使用您喜欢的语言的类似IC()函数,请打开“拉”请求! icecream的目标是用每种语言中的方便的iC()功能加甜打印调试。
通过命令行克隆项目: