Jak uniknąć plików .pyc?


268

Czy mogę uruchomić interpreter Pythona bez generowania skompilowanych plików .pyc?

Odpowiedzi:


288

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_bytecodezmienna, 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 .pycplikami, wprowadzając specjalny __pycache__podfolder, zobacz Co nowego w Python 3.2 - Katalogi repozytoriów PYC .


1
Przynajmniej w OS X 10.8 z uruchomionym Pythonem 2.7 zmienna środowiskowa nie działa.
sorin,

5
Jeśli osadzasz interpreter (w programie C ++), użyj „Py_DontWriteBytecodeFlag = 1;” w twoim kodzie źródłowym. To jest globalny int zadeklarowany w pydebug.h.
JimB

1
Zmienna środowiskowa działa dobrze dla mnie w 2.7, nie wiem, jakie problemy mają inni. Dzięki!
Thomas,

8
Pracowałem także dla OSX (10.8 i 10.10); @sorin czy poprawnie wyeksportowałeś zmienną? export PYTHONDONTWRITEBYTECODE=1
nevelis,

1
Czy wiesz, jak zrobić to samo z pytestem?

110
import sys

sys.dont_write_bytecode = True

25
Właśnie próbowałem tego i działa w przypadku importowanych modułów. W szczególności, po ustawieniu tej zmiennej cokolwiek zaimportowane później nie wygeneruje plików pyc. To jest zachwycające. Dzięki.

Zamiast dodawać to w module nadrzędnym, spróbuj dodać to w odnośnym skrypcie. To działa świetnie. Podziękowania dla @te wilson
Sathy

4
Dodaj to do swojego, site-packages/usercustomize.pyaby 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/…
RobM

3
Moje pakiety witryn znajdowały się pod adresem: /usr/local/lib/python2.7/site-packages i musiałem utworzyć usercustomize.py
anon58192932

3
Lub w jednym wierszu:import sys; sys.dont_write_bytecode = True
ET-CS

23

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.


11

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”


7

Możesz ustawić sys.dont_write_bytecode = Truew swoim źródle, ale musiałoby to być w pierwszym załadowanym pliku Pythona. Jeśli wykonasz python somefile.pyto nie dostaniesz somefile.pyc.

Po zainstalowaniu narzędzia za pomocą setup.pyi entry_points=będzie ustawiony sys.dont_write_bytecodew 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.pyci tak nie zostanie wygenerowany, ale nie zostaną .pyczaimportowane żadne pliki dla innych plików.

Jeśli masz jakieś narzędzie myutili nie możesz tego zmienić, nie przekaże -B do interpretera Pythona. Po prostu zacznij od ustawienia zmiennej środowiskowej PYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil

4

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ń.


4

Począwszy od Python 3.8 , możesz użyć zmiennej środowiskowej PYTHONPYCACHEPREFIXdo 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 ./profileLinuksa 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/


2

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.


2

Rozwiązanie dla ipython 6.2.1 using python 3.5.2 (testowane na Ubuntu 16.04 i Windows 10):

Ipythonnie szanuje, %env PYTHONDONTWRITEBYTECODE =1jeśli jest ustawiony w ipythoninterpretatorze 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

0

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ą.


Często stwierdziłem, że istnieją nieaktualne .pycpliki kodów bajtowych . Z jakiegoś powodu, gdy zmieniam klasę / moduł, .pycplik nie jest aktualizowany. Więc kiedy zaimportuję go po zmianie .pypliku, nadal będzie go używać .pyc, co prowadzi do błędów
alpha_989
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.