.Pyc dosyaları ne zaman yenilenir?


93

".Pyc" dosyalarının, programların daha hızlı çalışmasını sağlamak için çalışma zamanında oluşturulan düz metin ".py" dosyalarının derlenmiş sürümleri olduğunu anlıyorum. Ancak birkaç şey gözlemledim:

  1. "Py" dosyalarının değiştirilmesi üzerine program davranışı değişir. Bu, "py" dosyalarının derlendiğini veya en azından yeniden derlenmeleri gerekip gerekmediğini anlamak için bir tür karma işlem veya zaman damgalarını karşılaştırmaya gittiğini gösterir.
  2. Tüm ".pyc" dosyalarını ( rm *.pyc) sildikten sonra bazen programın davranışı değişir. Bu, ".py" güncellemelerinde derlenmediklerini gösterir.

Sorular:

  • Ne zaman derleneceklerine nasıl karar veriyorlar?
  • Geliştirme sırasında daha sıkı kontroller yapmalarını sağlamanın bir yolu var mı?

15
.Pyc dosyalarını .pyc ile silmekten kaçının rm *.pyc. Bu, iç içe klasörlerdeki .pyc dosyalarını silmez. find . -name '*.pyc' -deleteBunun yerine kullanın
Zags

6
Belki sorunuzla ilgili bir not: Bir program, bir '.pyc' veya '.pyo' dosyasından okunduğunda, bir '.py' dosyasından okunduğundan daha hızlı çalışmaz; ".pyc" veya ".pyo" dosyalarında daha hızlı olan tek şey, yüklendikleri hızdır. bağlantı
maggie

@maggie yükleme ve yürütme süresi arasındaki fark nedir?
Daniel Springer

3
@Dani yükleme, programı okumak ve sonra derlemek için gereken süredir. Yürütme zamanı, yüklendikten sonra gerçekleşen programın gerçekten çalıştırıldığı zamandır. Teknik olmak istiyorsanız, zaman türleri yükleme süresi, derleme süresi, bağlantı süresi ve yürütme süresidir. Bir .pyc oluşturmak derleme zaman bölümünü ortadan kaldırır.
Eric Klien

@EricKlien teşekkürler dostum
Daniel Springer

Yanıtlar:


81

.pycDosyalar python'un dosyası diğer bazı komut dosyası tarafından ithal yalnızca oluşturulan (ve muhtemelen yazılır) vardır. İçe aktarma çağrılırsa, Python .pycdosyanın dahili zaman damgasının karşılık gelen .pydosyadan daha eski olup olmadığını kontrol eder . Eğer öyleyse .pyc; Değilse veya .pychenüz yoksa, Python .pydosyayı a olarak derler .pycve yükler.

"Daha sıkı kontrol" ile neyi kastediyorsunuz?


3
İle sorunları çözebiliyorum rm *.pyc. Tüm dosyaları yeniden oluşturulmaya zorlarsam, dosyaların kendileri tarafından yeniden derlenmediğini belirten bazı sorunların çözüleceğini biliyorum. Sanırım zaman damgalarını kullanırlarsa, bu davranışı daha katı hale getirmenin bir yolu yoktur, ancak sorun hala devam etmektedir.
Aaron Schif

14
Bu tam olarak doğru değil. Zaman damgalarının eşleşmesi gerekmez (ve genellikle yoktur). Yeniden derlemeyi tetiklemek için zaman damgasının karşılık gelen zaman damgasından daha eski.pyc olması gerekir . .py
Tim Pietzcker

4
@Aaron, Muhtemelen .py dosyalarını değiştiriyor musunuz ve bu süreçte onları eski hale getiriyor musunuz (örneğin, onları başka bir dizinden kopyalayarak, 'değiştirme zamanını' koruyan bir işlem kullanarak)?
greggo

1
@greggo, git kullanıyorum ve bir depodan güncelleme yapıyorum, yani evet bir şekilde öyleyim. Bu yapabilirdi. Teşekkürler.
Aaron Schif

1
Bunu bildiğim iyi oldu. Cevabınızı düzeltmeye ne dersiniz?
Piotr Dobrogost

31

.pyc dosyaları, karşılık gelen kod öğeleri içe aktarıldığında oluşturulur ve ilgili kod dosyaları güncellendiyse güncellenir. .Pyc dosyaları silinirse, otomatik olarak yeniden oluşturulurlar. Ancak, bunlar edilir değil tekabül kod dosyaları silindiğinde otomatik olarak silinir.

Bu, dosya düzeyinde yeniden yapılandırmalar sırasında gerçekten eğlenceli hatalara neden olabilir.

Her şeyden önce, yalnızca makinenizde ve başka hiç kimsede çalışmayan kodu zorlayabilirsiniz. Sildiğiniz dosyalar için sarkan referanslarınız varsa, ilgili .pyc dosyalarını manuel olarak silmediğinizde bunlar yerel olarak çalışmaya devam eder, çünkü .pyc dosyaları içe aktarmalarda kullanılabilir. Bu, uygun şekilde yapılandırılmış bir sürüm kontrol sisteminin .py dosyalarını .pyc dosyalarına değil, yalnızca merkezi depoya göndereceği gerçeğiyle birleşir, bu da kodunuzun "içe aktarma testini" geçebileceği (her şey yolunda mı) olduğu ve iyi olmadığı anlamına gelir. başkasının bilgisayarında çalışmak.

İkincisi, paketleri modüllere dönüştürürseniz oldukça korkunç hatalar yaşayabilirsiniz. Bir paketi ( __init__.pydosya içeren bir klasör ) bir modüle (.py dosyası) dönüştürdüğünüzde, bir zamanlar bu paketi temsil eden .pyc dosyaları kalır. Özellikle __init__.pyckalıntılar. Öyleyse, önemli olmayan bazı kodlara sahip foo paketine sahipseniz, daha sonra bu paketi silin ve bazı işlevlere sahip bir foo.py dosyası oluşturun def bar(): passve çalıştırın:

from foo import bar

alırsın:

ImportError: cannot import name bar

çünkü python hala foo paketindeki eski .pyc dosyalarını kullanıyor, hiçbiri bar'ı tanımlamıyor. Bu, özellikle .pyc dosyaları nedeniyle tamamen çalışan kodun bozulabildiği bir web sunucusunda sorunlu olabilir.

Bu iki nedenin (ve muhtemelen diğerlerinin) bir sonucu olarak, dağıtım kodunuz ve test kodunuz, aşağıdaki bash satırında olduğu gibi .pyc dosyalarını silmelidir:

find . -name '*.pyc' -delete

Ayrıca, python 2.6'dan itibaren, -B.pyc dosyalarını kullanmamak için python'u bayrakla çalıştırabilirsiniz . Bkz .pyc dosyaları nasıl engellenir? daha fazla ayrıntı için.

Ayrıca bkz: Tüm .pyc dosyalarını bir projeden nasıl kaldırırım?


"Bir modülü dönüştürdüğünüzde ( __init__.pydosya içeren bir klasör ) ...". Bu bir modül değil, bir paket olacaktır.
Robert David Grant

2
Özellikle __init__.pyckalıntılar. - Nasıl olur? Bir paket bir paket aracı silme dizini silme bir dizin olduğu için bu nedenle ... hiçbir dosya kalmayıncaya
Piotr Dobrogost

3
@PiotrDobrogost Düzgün yönetilen kaynak kontrolü, pyc dosyalarınızı kaynağa kontrol etmemeyi içerir. Bu nedenle, yerel kopyanızdaki pyc dosyaları dahil klasörü silebilirsiniz, ancak git çekme işlemi yapan başka biri için silinmeyecektir. Dağıtımınız bir git çekme içeriyorsa, bu durum sunucunuzu çökertebilir.
Zags

Geliştirme ortamınızın kodunuzun nereye dağıtılacağını temsil etmesine güvenmemek için birçok neden vardır. Bu .pycsorunun bir nedeni de var: İşletim sistemi ve yardımcı program yama seviyelerine, .sodosyalara, yapılandırma dosyalarına, diğer Python kitaplıklarına (sanal ortamda çalışmıyorsanız), belirsiz ortam değişkenlerine yönelik gizli bağımlılıklar ... liste devam ediyor. Kapsamlı olmak ve tüm bu tür sorunları bulmak için, kodunuzun temiz bir kopyasını bir git deposunda yapmanız veya PyPi tarzı bir sunucuya paket olarak yayınlamanız ve yeni bir VM'de tam bir klon veya kurulum yapmanız gerekir. Bu olası sorunlardan bazıları, bu .pyckonuyu kıyaslandığında soluk hale getiriyor .
Chris Johnson
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.