Uruchamianie Pythona w Windows
+ 02.03.2024 + 05.06.2024
Szukanie ścieżek do plików .exe *
Python Launcher for Windows *
Instalacja kolejnej wersji Python *
cmd - przerwij gdy błąd
Wyszukiwanie dostępnych wersji Pythona w Windows
W SKRÓCIE
Reguły, które zamierzam sobie stosować:
- Uruchamianie plików *.py jako skryptów Windows przez py.exe tj. Python Launcher for Windows, głównie z opcją wynikającą z pierwszeństwa na liście ścieżek do python.exe w zmiennej środowiskowej PATH.
- Używanie w pierwszym wierszu pliku *.py:
#!/usr/bin/env python
- właśnie celu korzystania z PATH (na końcu nie może być żadnych cyfr - tylko samo python) - W “Edytuj zmienne środowiskowe systemu” należy po instalacji kolejnej wersji Pythona przenieść ścieżki do Python.exe z Path - system do Path - użytkownika, żeby umożliwić sobie wygodniejszą ich modyfikację. - Zdaje się, że w nowszych wersjach ścieżka już od razu jest w Path - użytkownika.
- Na pierwszym miejscu w Path - użytkownika wpisuję %PY_PTH%, a zmienną środowiskową PY_PTH ustawiam domyślnie na .venv\Scripts np. poleceniem
setx PY_PTH .venv\Scripts
(to daje ścieżkę względną w Path). W ten sposób skrypt uruchamiany z miejsca, gdzie jest wygenerowane środowisko wirtualne będzie wywoływał python.exe właśnie z tego środowiska. Dla doraźnej potrzeby można zmieniać PY_PTH na inną ścieżkę. - W Path - użytkownika_ poniżej %PY_PTH% umieszczam ścieżkę do wybranego python.exe, który ma być uruchamiany, gdy nie korzystam ze środowiska wirtualnego. Można też dodać do Path folder Scripts.
- Na sam koniec Path - użytkownika przenoszę
%USERPROFILE%\AppData\Local\Microsoft\WindowsApps
,
żeby się nie włączał sklep Microsoft po wywołaniu python.exe - Środowsko wirtualne generuję w miejscu (tj. folderze) skryptu *.py za pomocą:
ścieżka\do\wzorcowego\python.exe -m venv .venv .venv\Scripts\python -m pip install --upgrade pip setuptools wheel setx PY_PTH .venv\Scripts
Przy takich ustawieniach nie jest potrzebna aktywacja środowiska wirtualnego. Będzie się włączało to, które jest w folderze wywoływanego skryptu.
Ostatnie polecenie jest zbędne, gdy nie zmienialiśmy PY_PTH.
Szukanie plików “.exe” dostępnych poprzez PATH
where /t "$path:python.exe"
/t
- można pominąć; wtedy nie wyświetla się rozmiar i data pliku. Albo where /t python.exe
w jakimś folderze gdzie nie ma “python.exe”:
Przeszukiwanie w głąb całych folderów
where /r "C:\\" /t python.exe
Uwaga - to chwilę trwa. Tu po /r
jest nazwa foldera, od którego zaczyna się szukanie - chyba powinno się stosować podwójne \\
np. dla całego dysku: C
Znalezioną ścieżkę “python.exe” można trwale zapamiętać w PATH (w menu START zacznij pisać “Edytuj zmienne środowiskowe dla konta” lub “… dla systemu”). Wtedy python
lub python mójSkrypt.py
będzie wywoływało właśnie tą wersję. Można też modyfikować PATH tuż przed wywołaniem python
w linii poleceń lub w pliku *.cmd. Jeśli używamy tekstów UTF-8 (np. w nazwach plików) to warto na początek włączyć to kodowanie w linii poleceń: chcp 65001
.
Gdy mamy swoje moduły, używane w różnych projektach to można dodać
set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib
Python Launcher for Windows
Od wersji 3.3 wraz z instalacją Pythona jest instalowany program py.exe
oraz pyw.exe
, np. C:\Windows\py.exe
, który pozwala na kompilację wprost poprzez uruchamianie pliku *.py
. W pierwszym wierszu naszego skryptu *.py
można wpisać np. #!python3.7-64
lub #!/usr/bin/python3.7-64
(w Windows /usr/bin/
jest pomijany).
Natomiast specjalne znaczenie ma #!/usr/bin/env python
- wg. dokumentacji następuje tu przeszukiwanie ścieżki PATH w celu uruchomienia pierwszego(?) napotkanego Python.exe . Jest to również przydatna opcja do uruchamiania środowiska wirtualnego (Uwaga - niestety nie można wpisać np. #!/usr/bin/env python3, i to pomimo tego, że python3.exe jest znajdywalny w PATH. Gdy tylko użyjemy jakichś cyfr, to sposób uruchamiania ignoruje /usr/bin/env i działa wg. reguły poszukiwania wersji determinowanej przez te cyfry.
Aby przetestować który kompilator się uruchamia można przygotować sobie testowy plik v.py:
#!/usr/bin/env python
import sys
input('\n'.join(['',sys.executable,sys.version,'','nacisnij Enter']))
Lista wersji kompilatorów do wyboru m.in za pomocą #!....
:
py -0p
py
bez parametrów wywołuje swój domyślny kompilator python.exe
- oznaczany na liście gwiazdką. Ale gdy uruchamiamy jakiś plik z pierwszym wierszem #!…, to to ustawienie ma priorytet. Generalnie wywołanie z py
może dawać całkiem inne efekty niż z python
(wyszukany w PATH).
Sprawdzenie aktualnej obsługi pliku *.py
- skopiuj do linii poleceń:
for /f "tokens=2 delims==" %i in ('assoc .py') do (ftype %i)
Można też znaleźć bardziej rozbudowane wersje takiego sprawdzania: FOR /F "tokens=2* delims==" %G IN ('assoc .py') DO for /f "tokens=2* delims==" %a in ('ftype %G') do @echo %a
Przypisanie aplikacji do rozszerzenia “.py” w linii poleceń administratora (cmd
[Ctrl+Shift+Enter] ):
ASSOC .py=Python.File
FTYPE Python.File="C:\WINDOWS\py.exe" "%L" %*
Jest to już zrobione jak w tym przykładzie, jeśli instalowaliśmy jakikolwiek pakiet PYTHONa 3.3+.
Uwaga - jeśli dodaliśmy swoją obsługę plików *.py (poprzez “Otwórz za pomocą”), to ten nasz wybór będzie miał priorytet nad powyższą konfiguracją. Aby to naprawić należy wybierać do uruchomienia *.py aplikację Python z ikoną rakiety . Wybieranie wprost “C:\WINDOWS\py.exe” jest błędem.
Ewentualnie, aby uruchamiać skrypt podając samą nazwę bez wpisywania rozszerzenia “.py” można jeszcze dodać set PATHEXT=.PY;%PATHEXT%
lub trwale zmodyfikować PATHEXT w “Edytuj zmienne…”.
Więcej inf. o aktualnym stanie konfiguracji, np. z pliku %LocalAppData%\py.ini
uzyskamy włączając PYLAUNCH_DEBUG
:
set PYLAUNCH_DEBUG=1 & py -0p
. Następnie można uruchamiać plik testowy v.py z rożnymi opcjami w #!…
Przykładowy wynik działania opcji PYLAUNCH_DEBUG
dla #!/usr/bin/env python
w pliku v.py z kodowaniem utf-8-BOM:
File 'C:\Users\user\AppData\Local\py.ini' non-existent File 'C:\Windows\py.ini' non-existent Called with command line: "C:\test\v.py" maybe_handle_shebang: read 112 bytes maybe_handle_shebang: BOM found, code page 65001 parse_shebang: found command: python searching PATH for python executable Python on path: C:\Kompil\Python36-32\python.exe ...
set PY_PYTHON=3
& set PY_PYTHON3=3.6-32
-
ustala domyślną wersję dla
uruchamianych *.py.
Równoważny zapis w py.ini
:
[defaults]
python=3
python3=3.6-32
Skutecznie działa również set PY_PYTHON=3.6-32
, lub trwale pamiętane setx PY_PYTHON 3.6-32
i ma pierwszeństwo nad py.ini
. Działanie zmiennych jest takie samo (?) jak dane w py.ini
po pominięciu PY_
. https://docs.python.org/3.5/using/windows.html#shebang-lines. W py.ini
może być np. tylko:
[defaults]
python=3.11-64
Z linii poleceń można dopisać tekst do swojego py.ini (modyfikacja działa od razu i nie trzeba restartu aplikacji np. cmd albo N++ jak w przypadku SetX):
(echo:[defaults]&echo:python=3.11-64)>%LocalAppData%\py.ini
Sprawdzenie: type %LocalAppData%\py.ini
W środowisku wirtualnym (zob.^) regułą nadrzędną jest wywołanie aktywowanego kompilatora Python.exe.
Można tu jeszcze wspomnieć o wymyślaniu własnych poleceń wpisywanych w py.ini, które można używać w #!….,tylko należy pamiętać, że nie mogą zaczynać się od python.
Można wyświetlić ścieżki PATH w linii poleceń wstawiając łamanie wierszy:
echo:%PATH:;=; & echo:%
Uwaga - Path jest składana z 2 części, które w “Edytuj zmienne…” widzimy jako - Path - system (priorytetowa) i Path - użytkownika. Warto je sobie uporządkować jak opisano na początku artykułu.
Można też wyświelić aktualny stan środowiska wykonując w oknie cmd
polecenia:
echo:&echo|set /p="*** %computername% %date% " & for /f "tokens=1,2,* " %G in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"') do @echo setx /m %G "%I echo:&echo|set /p="*** %username% " & for /f "tokens=1,2,* " %G in ('reg query "HKCU\Environment"') do @echo setx %G "%I
… albo wykonując skrypt get_environment.cmd:
@echo off echo|set /p="*** %computername% %date% " for /f "tokens=1,2,* " %%G in ( 'reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' ) do echo setx /m %%G "%%I echo|set /p="*** %username% " for /f "tokens=1,2,* " %%G in ( 'reg query "HKCU\Environment"' ) do echo setx %%G "%%I
Zauważ, że w poleceniach setx mamy celowo niezamknięty cudzysłów "
("%%I
).
Instalacja kolejnej wersji Python w Windows
1 . Uruchom: cmd /k py -0p
- aby ustalić położenie obecnie używanego kompilatora Python.exe (i obok zainstalować nowszą wersję).
2 . Tu jest dobry moment aby zapamiętać zainstalowane globalnie biblioteki przez pip install ...
: py -m pip freeze
- ale część z nich jest zainstalowana jako pochodna innych instalacji, więc może lepiej sobie zapamiętywać sukcesywnie w pliku kolejne doinstalowane moduły, albo skorzystać ze skryptu:
Python pip_install_list.py ...
. . .
# Lista modułów zainstalowanych przez `pip install`
import subprocess # https://stackoverflow.com/questions/4760215/
import re
py = 'py' # py='c:\Kompil\Python39\python'
pip_freeze = subprocess.run([py,'-m','pip','freeze'], capture_output=True, text=True).stdout
# 'rauth==0.7.3\nrequests==2.25.1\n...
modules = [re.sub(r'==.+$', '', m) for m in pip_freeze.split()] # bez `==v.x.y`
# ['rauth','requests',...
print('\n'.join([f'''py -m pip install {m}''' for m in modules]))
####################################################
#Wyszukanie modułów głównych z pominięciem zależnych (to trochę trwa!)
mGl = set()
for m in modules:
print(f''' === {m} === ''')
pip_show = subprocess.run([py,'-m','pip','show', m], capture_output=True, text=True).stdout
# print('-.-.-\n',pip_show)
# -.-.-
# Name: requests
# ...
# Requires: certifi, chardet, idna, urllib3
# Required-by: rauth
# ...
# Zdarzają się błędy, które raczej nie dotyczą wiersza 'Requires: ...
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 ...
if not pip_show: continue # >>>>>>>>
match = re.search(r'^Requires: (.*)$[\r\n]+^Required-by: (.*)$', pip_show, flags=re.MULTILINE)
if match: # np. match[1] -> 'certifi, chardet, idna, urllib3', match[2] -> 'rauth'
print(match[0]) # 'Requires: certifi, chardet, idna, urllib3\nRequired-by: rauth'
if match[2] == '':
mGl.add(m)
print('\n ',"Moduły nadrzędne:")
print('\n'.join([f'''py -m pip install {m}''' for m in mGl]))
PowerShell pip_install_list.ps1 ...
. . .
# Lista modułów zainstalowanych przez `pip install` (bez `==v.x.y`)
($m = (py -m pip freeze).Split("`n") | foreach { $_ -replace '==.+$', ''})
# Instalacja wszystkich modułów - spis:
# $m | foreach {"py -m pip install $($_)"}
###################################################
#Wyszukanie modułów głównych z pominięciem zależnych (to trochę trwa!)
$mGl = @{}
foreach ($k in $m) {
$k
$v = (py -m pip show $k) | Select-String "^Required-by"
if ($v.ToString().Length -le "Required-by: ".Length) {
$mGl[$k] = $v
}
}
# $mGl["rauth"] -> "Required-by: " (tzn. główny moduł)
# $mGl["requests"]-> "Required-by: rauth" (moduł zależny - sam się zainstaluje)
"Instalacja modułów głównych - spis"
$mGl.keys | foreach {"py -m pip install $($_)"}
- Download
4 . ➜ Install Now ...
[✓]
Add python.exe to PATH- ➜ Customize installation
[✓]
…[✓]
py launcher[_]
for all…[_]
[✓]
[✓]
[✓]
[_]
[_]
[_]
- Customize install location
[C:\Kompil\Python\Python311]
(wygodnie jest używać klarownej lokalizacji)
5 . W zmiennych środowiskowych użytkownika - PATH
- %PY_PTH% na pierwsze miejsce; usuwam ścieżki do starszych wersji Python.
- Uruchom
cmd
. Uruchom kontrolniepy -0p
, potempy
,exit()
.
7 . py -m pip install --upgrade pip setuptools wheel
8 . Odtwarzam potrzebne py -m pip install ...
z listy z p.2.
9 . Gdy nie potrzebuję poprzezdniej wersji to ją odinstalowywuję (a nie usuwam).
cmd - przerwij gdy błąd
py xyz.py "param. . ." || ( echo ___ERROR___ & pause & goto:EOF )
#!/usr/bin/env python - uruchamianie w Linux. Po zalogowaniu na root:
_ cd /usr/bin/
_ unlink python
_ ln -sv /usr/bin/python3 python
albo w ~/.bashrc dopisać:
_ alias python=python3
i potem uruchomić
_ source ~/.bashrc
Zob. też