1. 起因, 目的:
- 經常使用 pycharm 來調試深度學習項目,每次新建虛擬環境,都是顯示一堆不存在的名稱,刪也刪不掉。 總覺得很煩,是個痛點。決定深入研究一下。
2. 先看效果
效果是能行,而且清爽多了。
3. 過程:
下面是 grok 寫的的過程總結: 詳細過程在這里
清理 PyCharm 無效解釋器的探索與修改過程
問題發現
我在 PyCharm CE 2022.3(Win10 系統)中創建新項目時,發現“Base interpreter”下拉菜單里有一堆標著 [invalid]
的 Python 解釋器路徑,比如 C:\ProgramData\Anaconda3\envs\Pad\python.exe
。這些路徑對應的環境早已刪除,但 PyCharm 還“記著”它們,挺煩人。我決定清理掉這些無效路徑。
初步嘗試:清理緩存
一開始,我懷疑是 PyCharm 緩存問題。通過 C:\Users\Administrator\AppData\Local\JetBrains\PyCharmCE2022.3\caches
找到了緩存文件,嘗試手動刪除 caches
文件夾(rmdir /S /Q caches
),并在 PyCharm 中用 File > Invalidate Caches / Restart 清理。但無效路徑依然存在,說明問題不在緩存。
找到根源:jdk.table.xml
深入研究后,我發現 PyCharm 的解釋器配置存儲在 C:\Users\Administrator\AppData\Roaming\JetBrains\PyCharmCE2022.3\options\jdk.table.xml
。這是一個 XML 文件,包含所有 <jdk>
條目,每個條目記錄一個解釋器的 name
和 homePath
。無效路徑(比如 [invalid]
)就在這里。
第一次嘗試:手動編輯 XML
我用記事本打開 jdk.table.xml
,但文件太長,嵌套結構復雜,很難手動找 [invalid]
路徑。我需要一個能展開折疊 XML 的工具。
工具選擇:VS Code
我選了 VS Code(裝了 XML 插件),因為它輕量且支持展開折疊(Ctrl+K Ctrl+J
展開所有)。打開 jdk.table.xml
后,XML 結構清晰了,但手動刪除 <jdk>
條目還是太慢,我想用 Python 自動化。
代碼 1:解析 XML, 查看全部的 項目名稱和路徑
我寫了一個 Python 腳本,用 xml.etree.ElementTree
解析 XML,提取 <jdk>
的 name
和 homePath
:
import xml.etree.ElementTree as ET# 假設我們要解析的 XML 文件路徑(改成你自己的文件路徑)
# 完整路徑是:
# xml_file = r"C:\Users\Administrator\AppData\Roaming\JetBrains\PyCharmCE2022.3\options\jdk.table.xml"
xml_file = r"jdk.table.xml"# 像打開網頁一樣,解析 XML 文件
tree = ET.parse(xml_file)
root = tree.getroot() # 得到 XML 的“根節點”,就像 HTML 的 <html># 遍歷所有的 <jdk> 標簽,就像找 HTML 里的 <div class="item">
for jdk in root.findall('.//jdk'):# 找到 <name> 標簽的內容,相當于抓取 HTML 的 <h1> 標題name = jdk.find('name').get('value') if jdk.find('name') is not None else "無名英雄"# 找到 <homePath> 標簽的內容,相當于抓取 HTML 的 <a href>home_path = jdk.find('homePath').get('value') if jdk.find('homePath') is not None else "無家可歸"# 打印出來,就像把爬到的數據展示在控制臺print(f"JDK:{name}")# print(f"路徑:{home_path}")# print("--- 分隔線 ---")# print()# 輸出結果:
"""
JDK:Python 3.8 (Roll)
JDK:Python 3.8
JDK:Python 3.8 (m4)
JDK:Python 3.8 (Alex)
JDK:Python 3.8 (TF)
JDK:Python 3.8 (Yolo)
JDK:Python 3.8 (Dirty)
JDK:Python 3.8 (del_me)
JDK:Python 3.8 (QT)
JDK:Python 3.8 (PyTorch)
JDK:Python 3.8 (PyCharmLearningProject)
JDK:Python 3.8 (del_me) (2)
JDK:Python 3.8 (Torch)
JDK:Python 3.8 (pythonProject)
JDK:Python 3.8 (CV2)
JDK:Python 3.8 (Traffic)
JDK:Python 3.8 (dedeeee)
JDK:Python 3.8 (TensorFlow-GPU)
JDK:Python 3.8 (SpeechToText)
JDK:Python 3.8 (Start)
JDK:Python 3.8 (del_this)
JDK:Python 3.8 (OpenCV)
JDK:Python 3.8 (My_Spider)
JDK:Python 3.8 (del_this) (2)
JDK:Python 3.8 (del_here)
JDK:Python 2.7 (py27)
JDK:Python 3.8 (del_aaaa)
JDK:Python 3.8 (del)
JDK:Python 3.8 (Porxy_Server)
JDK:Python 3.8 (A)
JDK:Python 3.8 (web)
JDK:Python 3.8 (dek)
JDK:Python 3.6 (Torch_Old_Photo_To_New)
JDK:Python 3.6 (py36)
JDK:Python 3.6 (face)
JDK:Python 3.8 (Pad)
JDK:Python 3.8 (del_later)
JDK:Python 3.8 (del) (2)
JDK:Python 3.8 (delthis)
JDK:Python 3.9 (del_gis)
JDK:Python 3.8 (GSW)
JDK:Python 3.8 (deddd)
JDK:Python 3.8 (dd2)
JDK:Python 3.8 (WNT)
JDK:Python 3.8 (tf_25)
JDK:Python 3.11 (iMac)
JDK:Python 3.8 (Dogg)
JDK:Python 3.11 (pythonProject_del)
JDK:Python 3.8 (Algo)
JDK:altair
JDK:Python 3.8 (torch_tiny)
JDK:Python 3.10 (torch_new)
JDK:Python 3.10 (tf_faceswap)
JDK:Python 3.10 (fa)
JDK:Python 3.10 (Spiders)
JDK:Python 3.10 (OpenCV)
JDK:Python 3.8 (opencv_apps)
JDK:Python 3.10 (nvidia_labs)
JDK:Python 3.10 (del_me)
JDK:Python 3.10 (del_w1)
JDK:Python 3.10 (FakeFace)
JDK:Python 3.10 (My_Spider)
JDK:Python 3.11 (pythonProject)
JDK:Python 3.11 (pythonProject) (2)
JDK:Python 3.11 (del)
JDK:Python 3.7 (del2)
JDK:Python 3.7 (del_33)
JDK:Python 3.10 (littleSpider)
JDK:Python 3.10 (Yolo8)
JDK:Python 3.10 (torch_mxnet)
JDK:Python 3.10 (pyrr)
JDK:Python 3.10 (tf_15)
JDK:Python 3.8 (Utils)
JDK:Python 3.8 (Utils) (2)
JDK:Python 3.10 (Utils)
JDK:Python 3.10 (showMeWhy)
JDK:Python 3.10 (torch_310)
JDK:Python 3.10 (fb_faiss)
JDK:Python 3.10 (SDPA)
JDK:Python 3.10 (transformers_tf)
JDK:Python 3.10 (Explore_Github)
JDK:Python 3.8 (tf_deepface)
JDK:Python 3.8 (venv)
JDK:Python 3.8 (p45)
JDK:Python 3.8 (tf_deepface) (2)
JDK:Python 3.8 (Test_lab)
JDK:Python 3.10 (torch_220)
JDK:Python 3.10 (del)
JDK:Python 3.10 (delddd)
JDK:Python 3.10 (del_me_later)
JDK:Python 3.10 (stable-diffusion-web-app)
JDK:Python 3.10 (torch_210)
JDK:Python 3.10 (torch_201)
JDK:Python 3.10 (torch_112_Transformer)
JDK:Python 3.10 (st)
JDK:Python 3.10 (maybe_del)
JDK:Python 3.10 (djangoShop)
JDK:Python 3.10 (tf_swap_face)
JDK:Python 3.10 (github_io)
JDK:Python 3.10 (ScreenToCode)
JDK:Python 3.10 (QT6)
JDK:Python 3.7 (MoviesRecommend)
JDK:Python 3.8 (redash)
JDK:Python 3.7 (py37)
JDK:Python 3.9 (py39)
JDK:Python 3.7 (python_nlp)
JDK:Python 3.11 (Nuitka_MakeExe)
JDK:Python 3.10 (deldd)
JDK:Python 3.10 (Nuitka_MakeExe2)
JDK:Python 3.7 (tf_115)
JDK:Python 3.10 (torch_212)
JDK:Python 3.7 (tf_1.15)
JDK:Python 3.10 (python_flask_file_server)
JDK:spider
JDK:Python 3.10 (crawler)
JDK:spider (2)
JDK:Python 3.8 (a1)
JDK:Python 3.10 (just_spiders)
JDK:Python 3.10 (streamlit_clould)
JDK:Python 3.10 (QT)
JDK:Python 3.11 (Django_Blog)
JDK:Python 3.8 (d1)
JDK:Python 3.10 (p1)
JDK:Python 3.11 (p2)
JDK:Python 3.11 (honeybot)
JDK:Python 3.11 (d11)
JDK:Python 3.9 (del_later)
JDK:Python 3.11 (shop_app)
JDK:Python 3.9 (PyCharmLearningProject)
JDK:Python 3.10 (torch15)
JDK:Python 3.8 (torch_115)
JDK:voice
JDK:torch_201
JDK:torch_220
JDK:Python 3.10 (torch_113)
JDK:Python 3.10 (torch_1_9)
JDK:Python 3.7 (torch_191)
JDK:Python 3.8 (torch_192)
JDK:Python 3.9 (p39)
JDK:Python 3.11 (python_nlp)
JDK:Python 3.11 (音樂web開發)
JDK:Python 3.11 (music_app)
JDK:Python 3.11 (music_app) (2)
JDK:Python 3.11 (django_rest_api)
JDK:Python 3.11 (dj_basic)
JDK:Python 3.10 (del1111)
JDK:Python 3.10 (r_notebooks)
JDK:Python 3.10 (RR)
JDK:Python 3.10 (dddeledd_me)
JDK:Python 3.10 (RRR)
JDK:Python 3.11 (R3)
JDK:Python 3.11 (Silvia)
JDK:Python 3.11 (Group3Django)
JDK:Python 3.11 (RL)
JDK:Python 3.11 (MakeExe)
JDK:Python 3.8 (venv) (2)
JDK:Python 3.8 (RL_gym_py38)
JDK:Python 3.11 (Mobile_farm_robot_simulation-master)
JDK:Python 3.10 (det2)
JDK:Python 3.11 (smallApps)
JDK:Python 3.11 (face)
JDK:Python 3.9 (face_app)
JDK:Python 3.7 (trafficsign)
JDK:Python 3.10 (seg)
JDK:Python 3.10 (sd)
JDK:Python 3.10 (junk)
"""
運行后,輸出了所有解釋器名稱,比如 Python 3.8 (del_me)
,但我需要自動刪除路徑不存在的條目。
代碼2:刪除不存在的項目。
我加了 os.path.exists
檢查路徑,并嘗試刪除無效 <jdk>
:
import xml.etree.ElementTree as ET
import os# 按照你提供的路徑
xml_file = r"jdk.table.xml"# 像打開網頁一樣,解析 XML 文件
tree = ET.parse(xml_file)
root = tree.getroot() # 得到 XML 的“根節點”# 存儲要刪除的 <jdk> 元素和它們的父節點
jdk_to_remove = []# 遍歷所有的 <jdk> 標簽
for jdk in root.findall('.//jdk'):# 找到 <name> 和 <homePath> 標簽的內容name = jdk.find('name').get('value') if jdk.find('name') is not None else "無名英雄"home_path = jdk.find('homePath').get('value') if jdk.find('homePath') is not None else "無家可歸"# 打印出來,方便查看print(f"檢查 JDK:{name}, 路徑:{home_path}")# 檢查路徑是否存在if not os.path.exists(home_path):print(f"?? 路徑 {home_path} 不存在,標記為刪除!")# 找到 jdk 的父節點parent = rootfor ancestor in root.iter():for child in ancestor:if child == jdk:parent = ancestorbreakjdk_to_remove.append((jdk, parent))else:print("? 路徑存在,保留!")print()# 刪除標記的 <jdk> 元素
for jdk, parent in jdk_to_remove:parent.remove(jdk)print(f"已刪除無效 JDK:{jdk.find('name').get('value') if jdk.find('name') is not None else '無名英雄'}")# 保存修改后的 XML 文件
tree.write(xml_file, encoding="utf-8", xml_declaration=True)
print(f"🎉 清理完成!已保存到 {xml_file}")
print()
最終結果
PyCharm 的解釋器列表清爽了,再也沒有 [invalid]
路徑!
希望對大家有幫助。