最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在Windows系統(tǒng)下管理多版本Python的工具實現(xiàn)方案

 更新時間:2026年03月27日 09:20:55   作者:薛定諤的貓喵喵  
作為一名開發(fā)者,我的電腦上常年安裝著多個 Python 版本:2.7、3.7、3.8、3.9、3.10……每次需要切換時,要么手動修改系統(tǒng)環(huán)境變量?PATH,因此本文記錄了我從編寫 PowerShell 腳本、封裝成全局命令,到解決執(zhí)行策略限制的完整過程,需要的朋友可以參考下

手把手打造 Python 多版本管理工具,告別 PATH 混亂,輕松切換

寫在前面

作為一名開發(fā)者,我的電腦上常年安裝著多個 Python 版本:2.7、3.7、3.8、3.9、3.10……每次需要切換時,要么手動修改系統(tǒng)環(huán)境變量 PATH,要么在項目里硬編碼路徑,煩不勝煩。早就羨慕 Linux 下的 nvm(Node Version Manager)和 pyenv,于是決定在 Windows 上也造一個類似的輪子。

本文記錄了我從編寫 PowerShell 腳本、封裝成全局命令,到解決執(zhí)行策略限制的完整過程。最終的效果是:在 PowerShell 中直接輸入 pvm list、pvm use 3.9.10,就能像使用內(nèi)置命令一樣管理 Python 版本。

一、方案選擇:PowerShell 函數(shù) + 全局調(diào)用

實現(xiàn)一個“全局命令”通常有三種方式:

將腳本所在目錄添加到 PATH 環(huán)境變量
最正統(tǒng)的做法,任何命令行都能識別。但需要處理管理員權(quán)限(修改系統(tǒng) PATH)以及腳本執(zhí)行策略。

在 PowerShell Profile 中定義函數(shù)
僅在 PowerShell 中有效,但無需修改 PATH,權(quán)限要求低。適合純 PowerShell 用戶。

編寫批處理包裝器 + 添加 PATH
兼容 CMD 和 PowerShell,但同樣涉及 PATH 修改和提權(quán)。

考慮到我主要使用 PowerShell,且希望操作盡量簡單,我選擇了 方案二:在 PowerShell Profile 中定義一個函數(shù) pvm,該函數(shù)調(diào)用我的核心腳本 pvm.ps1。這樣只需要把腳本放在固定位置,然后在 profile 中寫一行函數(shù)定義,即可在任何 PowerShell 窗口中使用 pvm 命令。

二、核心腳本:pvm.ps1

首先編寫核心邏輯的 PowerShell 腳本。腳本的功能包括:

  • 列出所有已配置的 Python 版本
  • 顯示當(dāng)前正在使用的版本
  • 切換到指定版本(修改系統(tǒng) PATH,將目標(biāo)版本的路徑提到最前面)
  • 交互式菜單

完整代碼如下,你只需修改 $pythonVersions 哈希表中的路徑為你自己的實際安裝目錄即可。

# pvm.ps1 - Python Version Manager for Windows
param(
    [string]$Command,
    [string]$Argument
)
# 要求以管理員身份運行(因為要修改系統(tǒng) PATH)
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Error "此腳本需要以管理員身份運行。請右鍵點擊 PowerShell 并選擇「以管理員身份運行」,然后重試。"
    exit 1
}
# ---------- 配置區(qū)域:請根據(jù)您的實際安裝路徑修改 ----------
$pythonVersions = @{
    "2.7.3" = @{
        Path    = "D:\Develop\python-2.7.3"
        Scripts = "D:\Develop\python-2.7.3\Scripts"
    }
    "3.7.4" = @{
        Path    = "D:\Develop\Python37"
        Scripts = "D:\Develop\Python37\Scripts"
    }
    "3.7.9" = @{
        Path    = "D:\Develop\Python-3.7.9"
        Scripts = "D:\Develop\Python-3.7.9\Scripts"
    }
    "3.8.10" = @{
        Path    = "D:\Develop\python-3.8.10"
        Scripts = "D:\Develop\python-3.8.10\Scripts"
    }
    "3.9.10" = @{
        Path    = "D:\Develop\python-3.9"
        Scripts = "D:\Develop\python-3.9\Scripts"
    }
    "3.10.8" = @{
        Path    = "D:\Develop\python-3.10.8"
        Scripts = "D:\Develop\python-3.10.8\Scripts"
    }
}
# ---------------------------------------------------------
# 收集所有已知的 Python 相關(guān)路徑(用于后續(xù)過濾)
$allPythonPaths = @()
foreach ($ver in $pythonVersions.Keys) {
    $allPythonPaths += $pythonVersions[$ver].Path
    $allPythonPaths += $pythonVersions[$ver].Scripts
}
$allPythonPaths = $allPythonPaths | Where-Object { $_ -ne '' } | ForEach-Object { [System.IO.Path]::GetFullPath($_) }
# 獲取系統(tǒng) PATH(機(jī)器級別)
function Get-SystemPath {
    return [Environment]::GetEnvironmentVariable("Path", "Machine") -split ';' | Where-Object { $_ -ne '' }
}
# 設(shè)置系統(tǒng) PATH
function Set-SystemPath($paths) {
    $newPath = $paths -join ';'
    [Environment]::SetEnvironmentVariable("Path", $newPath, "Machine")
    $env:Path = $newPath   # 立即更新當(dāng)前會話
}
# 獲取當(dāng)前正在使用的 Python 版本(如果屬于管理列表則返回版本號,否則返回 $null)
function Get-CurrentPythonVersion {
    try {
        $pythonExe = (Get-Command python -ErrorAction Stop).Source
    } catch {
        Write-Warning "當(dāng)前 PATH 中未找到 python 命令。"
        return $null
    }
    $pythonExe = [System.IO.Path]::GetFullPath($pythonExe)
    foreach ($version in $pythonVersions.Keys) {
        $info = $pythonVersions[$version]
        $pythonDir = [System.IO.Path]::GetFullPath($info.Path)
        $expectedExe = Join-Path $pythonDir "python.exe"
        if ($pythonExe -eq $expectedExe) {
            return $version
        }
    }
    return $null
}
# 獲取當(dāng)前 Python 的完整路徑(用于顯示)
function Get-CurrentPythonPath {
    try {
        return (Get-Command python -ErrorAction Stop).Source
    } catch {
        return $null
    }
}
# 列出所有版本,并標(biāo)記當(dāng)前版本
function List-Versions {
    $current = Get-CurrentPythonVersion
    Write-Host "已安裝的 Python 版本:"
    foreach ($version in ($pythonVersions.Keys | Sort-Object)) {
        if ($version -eq $current) {
            Write-Host "* $version (當(dāng)前)" -ForegroundColor Green
        } else {
            Write-Host "  $version"
        }
    }
}
# 切換到指定版本
function Use-Version($version) {
    if (-not $pythonVersions.ContainsKey($version)) {
        Write-Host "錯誤:版本 '$version' 不存在。" -ForegroundColor Red
        return $false
    }
    $current = Get-CurrentPythonVersion
    if ($current -eq $version) {
        Write-Host "當(dāng)前已經(jīng)是 Python $version,無需切換。" -ForegroundColor Yellow
        return $true
    }
    # 新版本需要添加的路徑
    $newPaths = @($pythonVersions[$version].Path, $pythonVersions[$version].Scripts) | Where-Object { $_ -ne '' }
    $newPaths = $newPaths | ForEach-Object { [System.IO.Path]::GetFullPath($_) }
    # 獲取當(dāng)前系統(tǒng) PATH
    $currentPath = Get-SystemPath
    # 過濾掉所有已知的 Python 路徑
    $filteredPath = $currentPath | Where-Object {
        $item = $_
        try {
            $fullItem = [System.IO.Path]::GetFullPath($item)
        } catch {
            $fullItem = $item
        }
        $matched = $false
        foreach ($known in $allPythonPaths) {
            if ($fullItem -eq $known) {
                $matched = $true
                break
            }
        }
        -not $matched
    }
    # 構(gòu)建新 PATH:新路徑在前,其余在后
    $newPathList = $newPaths + $filteredPath
    Set-SystemPath $newPathList
    Write-Host "已切換到 Python $version。請重新打開命令行窗口以使更改完全生效。" -ForegroundColor Green
    return $true
}
# 主命令處理
if (-not $Command) {
    # 交互模式
    Write-Host "Python Version Manager (pyvm)"
    while ($true) {
        List-Versions
        $selected = Read-Host "`n請輸入要切換的版本號 (輸入 q 退出)"
        if ($selected -eq 'q') { exit }
        $result = Use-Version $selected
        if ($result) {
            $continue = Read-Host "是否繼續(xù)操作其他版本?(y/n)"
            if ($continue -ne 'y') { exit }
        }
    }
} else {
    switch ($Command.ToLower()) {
        'list' {
            List-Versions
        }
        'current' {
            $currentVer = Get-CurrentPythonVersion
            $currentPath = Get-CurrentPythonPath
            if ($currentVer) {
                Write-Host "當(dāng)前 Python 版本: $currentVer"
            } elseif ($currentPath) {
                Write-Host "當(dāng)前使用的 Python 不在管理列表中,路徑為: $currentPath" -ForegroundColor Yellow
            } else {
                Write-Host "當(dāng)前未檢測到 Python 命令。" -ForegroundColor Red
            }
        }
        'use' {
            if (-not $Argument) {
                Write-Error "請指定要使用的版本號。"
                exit 1
            }
            $result = Use-Version $Argument
            if (-not $result) { exit 1 }
        }
        default {
            Write-Error "未知命令: $Command。可用命令: list, current, use <version>"
            exit 1
        }
    }
}

將上述代碼保存為 pvm.ps1,放在一個固定路徑,例如 D:\Develop\pvm\pvm.ps1

三、將 pvm 變?yōu)槿置睿篜owerShell 函數(shù)

現(xiàn)在我們需要在 PowerShell 的配置文件中定義一個函數(shù) pvm,它負(fù)責(zé)調(diào)用 pvm.ps1 并傳遞參數(shù)。

打開 PowerShell Profile
在 PowerShell 中執(zhí)行:

notepad $PROFILE

如果提示文件不存在,選擇“是”創(chuàng)建。

添加函數(shù)定義
在打開的記事本中,輸入以下內(nèi)容(注意修改路徑為你的 pvm.ps1 實際位置):

function pvm { & "D:\Develop\pvm\pvm.ps1" @args }

保存并關(guān)閉文件。

重新加載 Profile
在 PowerShell 中執(zhí)行:

. $PROFILE

四、遇到的第一道坎:執(zhí)行策略限制

執(zhí)行 . $PROFILE 時,你可能遇到這樣的錯誤:

. : 無法加載文件 D:\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1,因為在此系統(tǒng)上禁止運行腳本。有關(guān)詳細(xì)信息,請參閱 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。

這是因為 PowerShell 默認(rèn)的執(zhí)行策略是 Restricted,禁止運行任何腳本(包括 profile 文件)。解決辦法是修改執(zhí)行策略。

解決方法

以管理員身份打開 PowerShell(右鍵開始菜單 → Windows PowerShell (管理員))。

執(zhí)行以下命令,將策略設(shè)置為 RemoteSigned

Set-ExecutionPolicy RemoteSigned

如果只想對當(dāng)前用戶生效,可以加 -Scope CurrentUser

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

按提示輸入 Y 確認(rèn)。

現(xiàn)在再次加載 profile:. $PROFILE,應(yīng)該就不會報錯了。

解釋RemoteSigned 策略允許運行本地未簽名的腳本,但會阻止從互聯(lián)網(wǎng)下載的未簽名腳本,既滿足了我們運行本地腳本的需求,又兼顧了安全性。

五、使用 pvm 命令

一切就緒后,我們可以在 PowerShell 中愉快地使用 pvm 了。

列出所有版本

pvm list

輸出示例:

已安裝的 Python 版本:
  2.7.3
  3.7.4
  3.7.9
  3.8.10
  3.9.10
* 3.10.8 (當(dāng)前)

查看當(dāng)前版本

pvm current

切換到指定版本(需要管理員權(quán)限):

pvm use 3.9.10

由于腳本需要修改系統(tǒng) PATH,請確保 PowerShell 是以管理員身份運行的。如果當(dāng)前不是管理員,可以右鍵點擊 PowerShell 圖標(biāo),選擇“以管理員身份運行”,然后再執(zhí)行 pvm use。

交互式模式

pvm

進(jìn)入交互菜單,顯示版本列表并提示輸入版本號切換。

六、進(jìn)階:自動提權(quán)(可選)

每次切換都要手動以管理員身份運行 PowerShell 挺麻煩的。我們可以在腳本中集成自動提權(quán)邏輯,當(dāng)檢測到?jīng)]有管理員權(quán)限時,自動彈出 UAC 窗口以管理員身份重啟腳本。

將 pvm.ps1 開頭的權(quán)限檢查替換為以下代碼:

# 檢查并自動提權(quán)
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Host "正在請求管理員權(quán)限..." -ForegroundColor Yellow
    Start-Process powershell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" $($MyInvocation.Line.Substring($MyInvocation.Line.IndexOf(' ') + 1))"
    exit
}

這樣,當(dāng)你執(zhí)行 pvm use 3.9.10 且當(dāng)前 PowerShell 不是管理員時,會自動彈出一個 UAC 確認(rèn)窗口,確認(rèn)后會在新的管理員窗口中執(zhí)行切換操作。切換完成后新窗口會關(guān)閉,原窗口仍保持。

七、常見問題

1. 切換后python --version還是舊版本?

  • 請確保已經(jīng)重新打開了新的命令行窗口。修改系統(tǒng) PATH 后,已打開的程序不會自動刷新,需要重啟。
  • 檢查是否處于 conda 環(huán)境中,conda deactivate 后再試。

2. 修改執(zhí)行策略后仍然報錯?

  • 確認(rèn)你是在管理員 PowerShell 中修改的(如果使用 -Scope CurrentUser 則無需管理員)。
  • 查看當(dāng)前策略:Get-ExecutionPolicy。
  • 如果策略是 Restricted,可能是修改未生效,嘗試重新執(zhí)行。

3. 切換時提示“找不到版本”?

  • 檢查 $pythonVersions 中的版本號與目錄是否對應(yīng),路徑是否存在。
  • 版本號大小寫敏感,建議使用數(shù)字和點號。

八、總結(jié)

通過 PowerShell 函數(shù) + 核心腳本的方式,我們成功在 Windows 上實現(xiàn)了一個輕量級的 Python 版本管理器。核心優(yōu)勢是:

  • 獨立:不依賴第三方工具,完全基于 PowerShell 和系統(tǒng) API。
  • 可控:代碼完全開源,可根據(jù)自己的安裝路徑隨意調(diào)整。
  • 易用pvm listpvm use 等命令直觀,與 nvm 風(fēng)格一致。

如果你也在 Windows 下被多 Python 版本困擾,不妨試試這個方案。所有代碼已在 Windows 10/11、PowerShell 5.1 和 7+ 上測試通過。歡迎評論區(qū)交流改進(jìn)!

附:完整項目文件結(jié)構(gòu)

D:\Develop\pvm\
  ├── pvm.ps1          # 核心腳本
  └── README.md        # 說明文檔(可選)

Profile 配置

# Microsoft.PowerShell_profile.ps1
function pvm {
    & "D:\Develop\pvm\pvm.ps1" @args
}

以上就是在Windows系統(tǒng)下管理多版本Python的工具實現(xiàn)方案的詳細(xì)內(nèi)容,更多關(guān)于Python多版本管理工具的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Python中l(wèi)ist[::-1]的幾種用法

    詳解Python中l(wèi)ist[::-1]的幾種用法

    這篇文章主要介紹了詳解Python中l(wèi)ist[::-1]的幾種用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • python將數(shù)據(jù)插入數(shù)據(jù)庫的代碼分享

    python將數(shù)據(jù)插入數(shù)據(jù)庫的代碼分享

    在本篇文章里小編給大家整理的是關(guān)于python將數(shù)據(jù)插入數(shù)據(jù)庫的代碼內(nèi)容,有興趣的朋友們可以參考下。
    2020-08-08
  • Python Requests訪問網(wǎng)絡(luò)更方便

    Python Requests訪問網(wǎng)絡(luò)更方便

    這篇文章主要介紹了使用Python Requests訪問網(wǎng)絡(luò),Python Requests 是一個非常強(qiáng)大的 HTTP 客戶端庫,用于發(fā)送 HTTP 請求,獲取響應(yīng)等操作,通過這個庫,你可以輕松地與 Web 服務(wù)進(jìn)行交互,實現(xiàn)各種網(wǎng)絡(luò)請求
    2024-01-01
  • 利用Opencv實現(xiàn)圖片的油畫特效實例

    利用Opencv實現(xiàn)圖片的油畫特效實例

    這篇文章主要給大家介紹了關(guān)于利用Opencv實現(xiàn)圖片的油畫特效的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Python+Turtle繪制可愛的多啦A夢的示例代碼

    Python+Turtle繪制可愛的多啦A夢的示例代碼

    這篇文章主要介紹了如何利用python中的Turtle模塊繪制一個童年記憶的卡通人物哆啦A夢,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-03-03
  • 如何使用Python和OpenCV進(jìn)行實時目標(biāo)檢測實例詳解

    如何使用Python和OpenCV進(jìn)行實時目標(biāo)檢測實例詳解

    這篇文章介紹了一個使用Python和OpenCV實現(xiàn)實時視頻流目標(biāo)檢測的程序,程序使用預(yù)訓(xùn)練的YOLOv3模型,并通過多線程處理提高性能,代碼展示了如何導(dǎo)入庫、初始化參數(shù)、加載模型、處理視頻幀以及顯示結(jié)果,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-11-11
  • 淺談Django學(xué)習(xí)migrate和makemigrations的差別

    淺談Django學(xué)習(xí)migrate和makemigrations的差別

    這篇文章主要介紹了淺談Django學(xué)習(xí)migrate和makemigrations的差別,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Python中私有屬性“_“下劃線和“__“雙下劃線區(qū)別

    Python中私有屬性“_“下劃線和“__“雙下劃線區(qū)別

    本文主要介紹了Python中私有屬性“_“下劃線和“__“雙下劃線區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • python中defaultdict的用法詳解

    python中defaultdict的用法詳解

    這篇文章主要為大家詳細(xì)介紹了python中defaultdict的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • python3 解決requests出錯重試的問題

    python3 解決requests出錯重試的問題

    這篇文章主要介紹了python3 解決requests出錯重試的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評論

四子王旗| 江安县| 渑池县| 沁源县| 枣强县| 方正县| 水城县| 南宁市| 库尔勒市| 晴隆县| 修水县| 若羌县| 宁国市| 南投县| 宜春市| 新邵县| 永清县| 花莲市| 荃湾区| 喀喇沁旗| 东明县| 和田县| 揭西县| 萍乡市| 天祝| 石柱| 安西县| 江油市| 蚌埠市| 宜黄县| 花莲市| 东丽区| 东阳市| 尼玛县| 调兵山市| 论坛| 读书| 兴宁市| 陕西省| 康乐县| 三门县|