Odpowiedzi:
Z „Co nowego w Pythonie 2.6 - Zmiany interpretera” :
Pythonowi można teraz uniemożliwić zapisywanie plików .pyc lub .pyo, podając przełącznik -B do interpretera języka Python lub ustawiając zmienną środowiskową PYTHONDONTWRITEBYTECODE przed uruchomieniem interpretera. To ustawienie jest dostępne dla programów w języku Python jako
sys.dont_write_bytecode
zmienna, a kod w języku Python może zmienić wartość, aby zmodyfikować zachowanie interpretera.
Aktualizacja 27.11.2010: Python 3.2 rozwiązuje problem zaśmiecania folderów źródłowych .pyc
plikami, wprowadzając specjalny __pycache__
podfolder, zobacz Co nowego w Python 3.2 - Katalogi repozytoriów PYC .
export PYTHONDONTWRITEBYTECODE=1
import sys
sys.dont_write_bytecode = True
site-packages/usercustomize.py
aby to dotyczyło wszystkich twoich skryptów. Dla mnie ten katalog był $HOME/.local/lib/python2.6/site-pacakges/usercustomize.py
. Por. docs.python.org/2/tutorial/…
import sys; sys.dont_write_bytecode = True
W Pythonie 2.3+ jest na to sposób, ale jest to trochę ezoteryczne. Nie wiem, czy zdajesz sobie z tego sprawę, ale możesz wykonać następujące czynności:
$ unzip -l /tmp/example.zip
Archive: /tmp/example.zip
Length Date Time Name
-------- ---- ---- ----
8467 11-26-02 22:30 jwzthreading.py
-------- -------
8467 1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32)
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip') # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'
Według biblioteki zipimport :
Dowolne pliki mogą być obecne w archiwum ZIP, ale tylko pliki .py i .py [co] są dostępne do importu. Import ZIP modułów dynamicznych (.pyd, .so) jest niedozwolony. Zauważ, że jeśli archiwum zawiera tylko pliki .py, Python nie będzie próbował zmodyfikować archiwum przez dodanie odpowiedniego pliku .pyc lub .pyo, co oznacza, że jeśli archiwum ZIP nie zawiera plików .pyc, import może być raczej powolny.
W związku z tym wystarczy skompresować pliki, dodać plik zip do ścieżki sys.path, a następnie zaimportować.
Jeśli budujesz to dla systemu UNIX, możesz również rozważyć spakowanie skryptu przy użyciu tego przepisu: plik wykonywalny unix zip , ale pamiętaj, że może być konieczne dostosowanie go, jeśli planujesz używać standardowego wejścia lub czytać cokolwiek z sys.args (może to być zrobione bez większych problemów).
Z mojego doświadczenia wynika, że wydajność nie cierpi z tego powodu zbyt wiele, ale powinieneś pomyśleć dwa razy przed zaimportowaniem w ten sposób bardzo dużych modułów.
W wersji 2.5 nie ma sposobu, aby to ukryć, oprócz środków takich jak nieudzielanie użytkownikom dostępu do zapisu do katalogu.
Jednak w Pythonie 2.6 i 3.0 w module sys może znajdować się ustawienie o nazwie „dont_write_bytecode”, które można ustawić, aby to ukryć. Można to również ustawić, przekazując opcję „-B” lub ustawiając zmienną środowiskową „PYTHONDONTWRITEBYTECODE”
Możesz ustawić sys.dont_write_bytecode = True
w swoim źródle, ale musiałoby to być w pierwszym załadowanym pliku Pythona. Jeśli wykonasz python somefile.py
to nie dostaniesz somefile.pyc
.
Po zainstalowaniu narzędzia za pomocą setup.py
i entry_points=
będzie ustawiony sys.dont_write_bytecode
w skrypcie uruchamiania. Nie można więc polegać na „domyślnym” skrypcie startowym generowanym przez setuptools.
Jeśli sam uruchamiasz Python z plikiem python jako argumentem, możesz określić -B
:
python -B somefile.py
somefile.pyc
i tak nie zostanie wygenerowany, ale nie zostaną .pyc
zaimportowane żadne pliki dla innych plików.
Jeśli masz jakieś narzędzie myutil
i nie możesz tego zmienić, nie przekaże -B do interpretera Pythona. Po prostu zacznij od ustawienia zmiennej środowiskowej PYTHONDONTWRITEBYTECODE
:
PYTHONDONTWRITEBYTECODE=x myutil
Mam kilka przypadków testowych w pakiecie testowym i zanim uruchomiłem pakiet testowy w terminalu Mac, tak:
python LoginSuite.py
Uruchomienie polecenia w ten sposób zapełniłem mój katalog plikami .pyc. Wypróbowałem poniższą metodę i to rozwiązało problem:
python -B LoginSuite.py
Ta metoda działa, jeśli importujesz przypadki testowe do zestawu testów i uruchamiasz pakiet w wierszu poleceń.
Począwszy od Python 3.8 , możesz użyć zmiennej środowiskowej PYTHONPYCACHEPREFIX
do zdefiniowania katalogu pamięci podręcznej dla Pythona.
Z dokumentacji Pythona:
Jeśli ta opcja jest ustawiona, Python zapisuje pliki .pyc w lustrzanym drzewie katalogów pod tą ścieżką, zamiast w katalogach pycache w drzewie źródłowym. Jest to równoważne z określeniem opcji -X pycache_prefix = PATH.
Przykład
Jeśli dodasz do ./profile
Linuksa następujący wiersz :
export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"
Python nie utworzy irytujących __pycache__
katalogów w katalogu projektu, zamiast tego umieści je wszystkie w katalogu~/.cache/cpython/
Możesz utworzyć katalogi, w których moduły istnieją tylko do odczytu dla użytkownika, na którym działa interpreter Pythona.
Nie sądzę, że istnieje bardziej elegancka opcja. PEP 304 wydaje się być próbą wprowadzenia prostej opcji, ale wydaje się, że został porzucony.
Wyobrażam sobie, że prawdopodobnie istnieje jakiś inny problem, który próbujesz rozwiązać, dla którego wyłączenie .py [co] wydaje się być obejściem, ale prawdopodobnie lepiej będzie zaatakować cokolwiek to pierwotny problem.
Rozwiązanie dla ipython 6.2.1 using python 3.5.2
(testowane na Ubuntu 16.04 i Windows 10):
Ipython
nie szanuje, %env PYTHONDONTWRITEBYTECODE =1
jeśli jest ustawiony w ipython
interpretatorze lub podczas uruchamiania w ~/.ipython/profile-default/startup/00-startup.ipy
. Zamiast tego użyj w swoim~.ipython/profile-default/startup/00-startup.py
import sys
sys.dont_write_bytecode=True
O ile wiem, Python skompiluje wszystkie moduły, które „importujesz”. Jednak Python NIE skompiluje uruchomienia skryptu python przy użyciu: „python script.py” (skompiluje jednak wszystkie moduły importowane przez skrypt).
Prawdziwe pytania brzmią: dlaczego nie chcesz, aby Python skompilował moduły? Prawdopodobnie możesz zautomatyzować sposób ich usuwania, jeśli ci przeszkadzają.
.pyc
pliki kodów bajtowych . Z jakiegoś powodu, gdy zmieniam klasę / moduł, .pyc
plik nie jest aktualizowany. Więc kiedy zaimportuję go po zmianie .py
pliku, nadal będzie go używać .pyc
, co prowadzi do błędów