小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

如何動(dòng)態(tài)調(diào)試Python的第三方庫(kù)

 imelee 2017-02-13

注意:本文方法僅限于調(diào)試安裝時(shí)附帶py源碼的庫(kù),如sklearn

引入

sklearn中的sklearn.feature_extraction.text.TfidfTransformer來(lái)獲取TF特征,但發(fā)現(xiàn)sklearn的計(jì)算結(jié)果與我手工計(jì)算結(jié)果不一樣。雖然能在github上找到sklearn源碼。但不能動(dòng)態(tài)調(diào)試,就無(wú)法直觀的看到結(jié)果。

那么問(wèn)題來(lái)了,我們?cè)趺礃硬拍軇?dòng)態(tài)調(diào)試Python的第三方庫(kù)(比如sklearn)呢?怎么樣才能看到第三方庫(kù)中源碼動(dòng)態(tài)運(yùn)行的中間結(jié)果?

假設(shè)我的代碼如下:

# 原始語(yǔ)料,3個(gè)文本
strs_train =[
'God is love',
'OpenGL on the GPU is fast',
'Doctor David is PHD']

from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
# 先提取 Bags of words特征
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(strs_train)
# 再基于Bags of words特征,變換為TF特征
tf_transformer = TfidfTransformer(use_idf=False).fit(X_train_counts)
X_train_tf = tf_transformer.transform(X_train_counts)
print(X_train_tf.todense())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

我怎么樣才能看到函數(shù)sklearn.feature_extraction.text.TfidfTransformer.transform()計(jì)算的中間結(jié)果呢?

Python調(diào)試基礎(chǔ)

Python自帶了一個(gè)用于調(diào)試代碼的模塊pdb。它支持?jǐn)帱c(diǎn)設(shè)置,單步調(diào)試,進(jìn)入函數(shù)調(diào)試,查看代碼片段,查看變量值,動(dòng)態(tài)改變變量值。

下面兩行代碼就能給程序加斷點(diǎn):

import pdb
pdb.set_trace()
  • 1
  • 2
  • 1
  • 2

加了斷點(diǎn),運(yùn)行程序,當(dāng)程序停下,就可以用下面幾個(gè)命令,在SHELL中調(diào)試代碼。

命令 含義
c 繼續(xù)執(zhí)行代碼
n 下一步
r 執(zhí)行代碼,從當(dāng)前函數(shù)返回
s 進(jìn)入函數(shù)
b 下斷點(diǎn)

調(diào)試Python第三方庫(kù)

我們用pdb,就可以在第三方庫(kù)中下斷點(diǎn),并進(jìn)行調(diào)試。這里以調(diào)試sklearn中的sklearn.feature_extraction.text.TfidfTransformer為例,給出如下步驟。

  • (1)找到第三方庫(kù)所在的位置

先利用如下Python代碼找到sklearn源碼位置。我的位置在C:\\Users\\biny\\Anaconda3\\lib\\site-packages\\sklearn。

import sklearn, os
path = os.path.dirname(sklearn.__file__)
  • 1
  • 2
  • 1
  • 2
  • (2)刪掉Python預(yù)編譯的字節(jié)碼

Python程序在運(yùn)行時(shí),為了提高運(yùn)行速度,Python解釋器先將.py代碼編譯為byte code字節(jié)碼),再有Python虛擬機(jī)來(lái)執(zhí)行字節(jié)碼。

下次再運(yùn)行同一程序時(shí),若.py代碼沒(méi)有改變,則省略將.py代碼編譯為字節(jié)碼的步驟,直接運(yùn)行上次已編譯好的字節(jié)碼

這些字節(jié)碼,會(huì)被存于__pycache__文件夾下,和.pyc文件。按照原理,這個(gè)步驟是不需要做的,不過(guò)刪掉字節(jié)碼在運(yùn)行自己的程序,如果不會(huì)出現(xiàn)新的字節(jié)碼文件,說(shuō)明你的第三方庫(kù)位置找錯(cuò)了。這樣能方便我們發(fā)現(xiàn)錯(cuò)誤。

  • (3)在第三方庫(kù)源碼中加斷點(diǎn)

根據(jù)第三方庫(kù)的位置,找到sklearn.feature_extraction.text.TfidfTransformer.transform()函數(shù)所在.py文件。并用pdb在函數(shù)開(kāi)頭加上斷點(diǎn)(如下)。

def transform(self, X, copy=True):
    import pdb
    pdb.set_trace()

    if hasattr(X, 'dtype') and np.issubdtype(X.dtype, np.float):
        # preserve float family dtype
        X = sp.csr_matrix(X, copy=copy)
    else:
        # convert counts or binary occurrences to floats
        X = sp.csr_matrix(X, dtype=np.float64, copy=copy)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • (4)運(yùn)行自己的程序

運(yùn)行我的代碼,停在第三方庫(kù)中,就可以用pdb命令調(diào)試第三方代碼了。

  • 此時(shí)代碼已經(jīng)運(yùn)行并進(jìn)入第三方庫(kù)中,停止在斷點(diǎn)處:
    C:\mine\tmp\debug_py_3rd_lib>python main.py

    c:\users\biny\anaconda3\lib\site-packages\sklearn\feature_extraction\text.py(1018)transform()
    -> if hasattr(X, ‘dtype’) and np.issubdtype(X.dtype, np.float):
    (Pdb)

  • 用n命令(next),讓代碼單步運(yùn)行到關(guān)鍵點(diǎn):

    c:\users\biny\anaconda3\lib\site-packages\sklearn\feature_extraction\text.py(1042)transform()
    -> if self.norm:
    (Pdb) n

  • 直接輸入要查看的中間變量(X.data),停下的這行代碼是即將執(zhí)行的,我們可以看到執(zhí)行前的變量值:

    c:\users\biny\anaconda3\lib\site-packages\sklearn\feature_extraction\text.py(1043)transform()
    -> X = normalize(X, norm=self.norm, copy=False)
    (Pdb) X.data
    array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

  • 繼續(xù)執(zhí)行代碼(n命令),然后可以看到中間變量值被改變。也能看到這個(gè)改變是因?yàn)樽隽?code>normalize。
    (Pdb) n

    c:\users\biny\anaconda3\lib\site-packages\sklearn\feature_extraction\text.py(1045)transform()
    -> return X
    (Pdb) X.data
    array([ 0.57735027, 0.57735027, 0.57735027, 0.40824829, 0.40824829,
    0.40824829, 0.40824829, 0.40824829, 0.40824829, 0.5 ,
    0.5 , 0.5 , 0.5 ])

記住調(diào)試結(jié)束后,一定要在第三方源碼中刪掉pdb斷點(diǎn)那兩行代碼!

參考

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多