.Pyc dosyaları nasıl önlenir?


268

Derlenmiş .pyc dosyalarını oluşturmadan python yorumlayıcısını çalıştırabilir miyim?

Yanıtlar:


288

Gönderen "Python 2.6 Yenilikler - Tercüman Değişiklikler" :

Python'un , Python yorumlayıcısına -B anahtarını sağlayarak veya yorumlayıcıyı çalıştırmadan önce PYTHONDONTWRITEBYTECODE ortam değişkenini ayarlayarak .pyc veya .pyo dosyalarını yazması engellenebilir . Bu ayar Python programları için sys.dont_write_bytecodedeğişken olarak kullanılabilir ve Python kodu yorumlayıcının davranışını değiştirmek için değeri değiştirebilir.

Güncelleme 2010-11-27: Python 3.2 , .pycözel bir __pycache__alt klasör tanıtarak kaynak klasörlerin dosyalarla karıştırılması sorununu giderir , bkz . Python 3.2 - PYC Havuz Dizinlerindeki Yenilikler .


1
En azından Python 2.7 çalıştıran OS X 10.8'de ortam değişkeninin etkisi yoktur.
sorin

5
Yorumlayıcıyı (C ++ programına) katıştırıyorsanız, "Py_DontWriteBytecodeFlag = 1;" kaynak kodunuzda. Bu, pydebug.h başlık dosyasında bildirilen global bir int'dir.
JimB

1
Çevre değişkeni 2.7'de benim için iyi çalışıyor, başkalarının ne gibi problemleri olduğunu bilmiyorum. Teşekkürler!
Thomas

8
Benim için de OSX'de çalıştı (10.8 ve 10.10); @sorin değişkeni düzgün bir şekilde dışa aktardınız mı? export PYTHONDONTWRITEBYTECODE=1
nevelis

1
Aynı şeyi pytest ile nasıl yapacağınızı biliyor musunuz?

110
import sys

sys.dont_write_bytecode = True

25
Sadece denedim ve ithal modüller için çalışıyor. Özellikle, bu değişken bir kez ayarlandıktan sonra içe aktarılan herhangi bir şey pyc dosyaları oluşturmaz. Bu çok hoş. Teşekkürler.

Bunu Ana Modüle eklemek yerine, referans verilen Komut Dosyasına eklemeyi deneyin. Bu harika çalışıyor. @Te wilson
Sathy

4
Bunu site-packages/usercustomize.pytüm komut dosyalarınız için geçerli kılmak üzere bunu adresinize ekleyin. Benim için bu dizin $HOME/.local/lib/python2.6/site-pacakges/usercustomize.py. Krş docs.python.org/2/tutorial/…
RobM

3
Site paketlerim şurada bulundu: /usr/local/lib/python2.7/site-packages ve ben usercustomize.py
anon58192932

3
Veya tek satırda:import sys; sys.dont_write_bytecode = True
ET-CS

23

Aslında bunu Python 2.3+ ile yapmanın bir yolu var, ama biraz ezoterik. Bunu fark edip etmediğinizi bilmiyorum, ancak aşağıdakileri yapabilirsiniz:

$ 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'

Göre zipimport kütüphanede:

ZIP arşivinde herhangi bir dosya bulunabilir, ancak yalnızca .py ve .py [co] dosyaları içe aktarılabilir. Dinamik modüllerin ZIP içe aktarılmasına (.pyd, .so) izin verilmez. Bir arşivde yalnızca .py dosyaları varsa, Python karşılık gelen .pyc veya .pyo dosyasını ekleyerek arşivi değiştirmeye çalışmaz. Bu, bir ZIP arşivi .pyc dosyaları içermiyorsa içe aktarmanın oldukça yavaş olabileceğini unutmayın.

Böylece, tek yapmanız gereken dosyaları sıkıştırmak, zip dosyasını sys.path'inize eklemek ve daha sonra içe aktarmaktır.

Bunu UNIX için oluşturuyorsanız, komut dosyanızı şu tarifi kullanarak paketlemeyi de düşünebilirsiniz: unix zip çalıştırılabilir , ancak stdin kullanmayı veya sys.args öğesinden bir şey okumayı planlıyorsanız bunu ayarlamanız gerekebilir. çok fazla sorun olmadan yapılır).

Deneyimlerime göre, bu nedenle performans çok fazla acı çekmiyor, ancak çok büyük modülleri bu şekilde içe aktarmadan önce iki kez düşünmelisiniz.


11

2.5'te, kullanıcılara dizine yazma erişimi vermemek gibi önlemler dışında, onu bastırmanın bir yolu yoktur.

Bununla birlikte, python 2.6 ve 3.0'da, sys modülünde "dont_write_bytecode" adlı ve bunu bastırmak için ayarlanabilecek bir ayar olabilir. Bu, "-B" seçeneğini ileterek veya "PYTHONDONTWRITEBYTECODE" ortam değişkenini ayarlayarak da ayarlanabilir.


7

sys.dont_write_bytecode = TrueKaynağınızda ayarlayabilirsiniz , ancak bunun yüklenen ilk python dosyasında olması gerekir. Eğer yürütürseniz python somefile.pyo zaman alamazsınız somefile.pyc.

Kullandığınız bir yardımcı program yüklediğinizde setup.pyve entry_points=ayarladığınız olacak sys.dont_write_bytecodebaşlatma komut. Bu nedenle setuptools tarafından oluşturulan "varsayılan" başlangıç ​​komut dosyasına güvenemezsiniz.

Python'u kendiniz argüman olarak python dosyasıyla başlatırsanız şunları belirtebilirsiniz -B:

python -B somefile.py

somefile.pycyine de oluşturulamaz, ancak .pyciçe aktarılan diğer dosyalar için de dosya yoktur .

Bazı yardımcı programlarınız varsa myutilve bunu değiştiremezseniz, -B'yi python yorumlayıcısına geçirmez. Sadece ortam değişkenini ayarlayarak başlayın PYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil

4

Bir test paketinde birkaç test durumu var ve Mac Terminalinde test paketini çalıştırmadan önce şöyle:

python LoginSuite.py

Komutu bu şekilde çalıştırarak dizinim .pyc dosyalarıyla dolduruluyordu. Aşağıda belirtilen yöntemi denedim ve sorunu çözdü:

python -B LoginSuite.py

Bu örnek, test senaryolarını test paketine içe aktarıyor ve paketi komut satırında çalıştırıyorsanız işe yarar.


4

Python 3.8 ile başlayarak PythonPYTHONPYCACHEPREFIX için bir önbellek dizini tanımlamak için ortam değişkenini kullanabilirsiniz .

Python belgelerinden:

Bu ayar yapılırsa, Python .pyc dosyalarını kaynak ağaçtaki pycache dizinleri yerine bu yoldaki bir ayna dizin ağacına yazar . Bu, -X pycache_prefix = PATH seçeneğini belirtmeye eşdeğerdir.

Misal

./profileLinux'taki şu satırı eklerseniz :

export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"

Python __pycache__proje dizininizde can sıkıcı dizinler oluşturmaz , bunun yerine hepsini altına koyar~/.cache/cpython/


2

Modüllerinizin Python yorumlayıcısının çalıştığı kullanıcı için salt okunur olarak var olduğu dizinleri yapabilirsiniz.

Daha zarif bir seçenek olduğunu sanmıyorum. PEP 304 bunun için basit bir seçenek sunma girişimi gibi görünmektedir, ancak terk edilmiş görünmektedir.

Muhtemelen çözmeye çalıştığınız başka bir sorun olduğunu hayal ediyorum, bunun için .py [co] 'un devre dışı bırakılması geçici bir çözüm gibi görünecektir, ancak bunun yerine bu orijinal sorunun ne olursa olsun saldırmak daha iyi olacaktır.


2

Çözüm ipython 6.2.1 using python 3.5.2(Ubuntu 16.04 ve Windows 10'da test edilmiştir):

Ipythonyorumlayıcıda veya başlatma sırasında %env PYTHONDONTWRITEBYTECODE =1ayarlanmışsa saygı göstermez . Bunun yerine,ipython~/.ipython/profile-default/startup/00-startup.ipy~.ipython/profile-default/startup/00-startup.py

import sys
sys.dont_write_bytecode=True

0

Bildiğim kadarıyla python "ithalat" tüm modülleri derleyecektir. Ancak python: "python script.py" kullanarak bir python betiği derlemeyecektir (betiğin aldığı tüm modülleri derleyecektir).

Gerçek sorular neden python'un modülleri derlemesini istemiyorsunuz? Muhtemelen engelliyorlarsa bunları temizlemenin bir yolunu otomatikleştirebilirsiniz.


Sık sık eski bayt kodu .pycdosyaları olduğunu gördüm . Nedense, sınıf / modülü değiştirdiğimde .pycdosya güncellenmiyor. .pyDosyayı değiştirdikten sonra içe .pyc
aktardığımda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.