您是否曾經使用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()
函數來簡化列印偵錯。