2014-06-17 76 views
10

我有很多PyCharm沒有正確識別庫中的函數的問題,所以我決定查看PyCharm錯誤識別的一些示例函數的源代碼。例如,PyCharm不能正確識別pickle.load();它認爲pickle.load()不接受任何參數,事實上它只帶一個參數。我問過這個問題here。所以我寫了以下簡短的測試代碼。PyCharm,什麼是python_stubs?

import pickle 


r = range(10) 
f = open("../temp/pickling_example.pkl", "wb") 
pickle.dump(r, f) 
f.close() 
f = open("../temp/pickling_example.pkl", "rb") 
pickle.load(f) 
print(r) 

我上pickle.load(f),倒數第二行按下Ctrl+B。我希望這會把我帶到包含pickle.load()定義的源文件,但它卻把我帶到了位置C:\Users\ray\.PyCharm30\system\python_stubs\-1442825926\_pickle.py的文件。該文件包含以下摘要(請參見下面的截圖)。

在這裏你可以看到PyCharm正確認識的pickle.load()簽名的問題的根源;根據這個文件的簽名pickle.load()沒有參數。

有人可以解釋爲什麼我被帶到這裏,這個文件是什麼,什麼python_stubs文件夾(更確切地說,C:\Users\ray\.PyCharm30\system\python_stubs\)是?

我的猜測如下。我在這個位置被帶到這個文件,因爲PyCharm在我的計算機上找不到定義pickle.load()的實際源代碼。在這些情況下,PyCharm只會生成一個虛擬文件,其中僅包含所使用函數的聲明(或僅簽名),在這種情況下,它是pickle.load()。當我按下Ctrl+Bpickle.load()時,這個文件是我被帶到的地方。這個文件的目的純粹是爲了使PyCharm的檢查工作正常,並且可以提供自動完成,PyCharm將所有這些文件都放入python_stubs目錄中。 pickle.load()函數的實際定義位於pycpyd文件中,位於我的C:\Python34\目錄中,而我沒有包含pickle.load()定義的實際py文件,因爲在安裝Python時,我沒有安裝源代碼。

問題:

(1)我的猜測大致正確嗎?你能提供更準確,更準確的方法嗎?(012)我能做些什麼來防止PyCharm錯誤地識別或不識別庫函數?我應該確保我總是安裝Python和所有第三方軟件包的源代碼,以確保PyCharm能夠正確地進行檢查嗎? (3)如果我是對的,PyCharm會生成這些文件,PyCharm如何猜測函數的簽名?

回答

6

(1)是的,你基本上是正確的。

python_stubs文件自動生成生成的文件包含內置函數的僞定義。它被PyCharm用來在它們沒有針對給定版本進行硬編碼的情況下推斷內建函數的類型。

(3)僅從他的文檔中正確推斷內置函數的類型並不總是可能的。有些文檔字符串開始與「類型簽名」:

>>> print(min.__doc__) 
min(iterable[, key=func]) -> value 
min(a, b, c, ...[, key=func]) -> value 

pickle.load()沒有。

請注意,這可能會在未來的python版本中改變,因爲從python3.4開始,Argument Clinic被引入,允許更好地檢查C中定義的內置插件。我不確定PyCharm是否已經能夠獲得信息。

(2)嘗試重建python骨架。但是,AFAIK是唯一真正的選擇,如果這不起作用,則打開PyCharm's issue tracker的門票。

+0

非常感謝你真正閱讀我真正長期的問題首先,更不用說你的輝煌答案!我真的不是什麼Python骷髏。這是一個Python概念還是一個PyCharm概念?任何指向我可以瞭解骨架的頁面的指針? – Ray

+2

@Ray這是一個PyCharm相關術語。 「骨架」是PyCharm從安裝和內置的庫中自動生成的所有文件,這些文件是提供其功能所需的。這包括生成'python_stubs'文件。當您啓動PyCharm時,您通常可以在狀態欄中看到有關重建項目解釋器的這些框架的一些消息。您應該能夠在重新啓動時強制重建,使緩存無效(在「文件」菜單下)。 – Bakuriu

相關問題