Döngüsel bağımlılıkları anlamak için Python'un aslında bir betik dili olduğunu hatırlamanız gerekir. Yöntemlerin dışındaki ifadelerin yürütülmesi derleme zamanında gerçekleşir. Import deyimleri tıpkı yöntem çağrıları gibi yürütülür ve onları anlamak için onları yöntem çağrıları gibi düşünmelisiniz.
İçe aktarma yaptığınızda, ne olacağı, içe aktardığınız dosyanın modül tablosunda zaten mevcut olup olmamasına bağlıdır. Varsa, Python o anda sembol tablosunda olanı kullanır. Değilse, Python modül dosyasını okumaya başlar, orada bulduğu her şeyi derler / yürütür / içe aktarır. Derleme zamanında referans verilen semboller, derleyici tarafından görülüp görülmediklerine veya henüz görülmeyeceklerine bağlı olarak bulunur veya bulunmaz.
İki kaynak dosyanız olduğunu hayal edin:
X.py dosyası
def X1:
return "x1"
from Y import Y2
def X2:
return "x2"
Y.py dosyası
def Y1:
return "y1"
from X import X1
def Y2:
return "y2"
Şimdi X.py dosyasını derlediğinizi varsayalım. Derleyici, X1 yöntemini tanımlayarak başlar ve ardından X.py'deki içe aktarma ifadesine ulaşır. Bu, derleyicinin X.py derlemesini duraklatmasına ve Y.py'yi derlemeye başlamasına neden olur. Kısa bir süre sonra derleyici Y.py'deki import ifadesine ulaşır. X.py zaten modül tablosunda olduğundan, Python, istenen tüm referansları karşılamak için mevcut tamamlanmamış X.py sembol tablosunu kullanır. X.py'de import ifadesinden önce görünen herhangi bir sembol artık sembol tablosundadır, ancak ondan sonraki semboller değildir. X1 artık import ifadesinden önce göründüğünden, başarıyla içe aktarılmıştır. Python daha sonra Y.py'yi derlemeye devam eder. Bunu yaparken Y2'yi tanımlar ve Y.py'yi derlemeyi bitirir. Daha sonra X.py'nin derlenmesine devam eder ve Y.py sembol tablosunda Y2'yi bulur. Derleme sonunda hatasız olarak tamamlanır.
Y.py'yi komut satırından derlemeye çalışırsanız çok farklı bir şey olur. Y.py'yi derlerken, derleyici Y2'yi tanımlamadan önce import ifadesine ulaşır. Ardından X.py'yi derlemeye başlar. Yakında X.py'deki Y2 gerektiren import ifadesine ulaşır. Ancak Y2 tanımsızdır, bu nedenle derleme başarısız olur.
Lütfen X.py'yi Y1'i içe aktaracak şekilde değiştirirseniz, hangi dosyayı derlerseniz derleyin, derlemenin her zaman başarılı olacağını unutmayın. Ancak, X2 sembolünü içe aktarmak için Y.py dosyasını değiştirirseniz, hiçbir dosya derlenmez.
X modülü veya X tarafından içe aktarılan herhangi bir modül mevcut modülü içe aktarabilirse, şunları KULLANMAYIN:
from X import Y
Döngüsel bir içe aktarım olabileceğini düşündüğünüz her zaman, diğer modüllerdeki değişkenlere derleme zamanı referanslarından da kaçınmalısınız. Masum görünen kodu düşünün:
import X
z = X.Y
Diyelim ki modül X, bu modül X'i içe aktarmadan önce bu modülü içe aktarıyor. Ayrıca, Y'nin X'de import ifadesinden sonra tanımlandığını varsayalım. O zaman bu modül içe aktarıldığında Y tanımlanmayacak ve bir derleme hatası alacaksınız. Bu modül önce Y'yi içe aktarırsa, bundan kurtulabilirsiniz. Ancak iş arkadaşlarınızdan biri üçüncü bir modüldeki tanımların sırasını masum bir şekilde değiştirdiğinde, kod bozulur.
Bazı durumlarda, bir import ifadesini diğer modüllerin ihtiyaç duyduğu sembol tanımlarının altına taşıyarak döngüsel bağımlılıkları çözebilirsiniz. Yukarıdaki örneklerde, import ifadesinden önceki tanımlar asla başarısız olmaz. Import ifadesinden sonraki tanımlar, derleme sırasına bağlı olarak bazen başarısız olur. Derleme sırasında içe aktarılan sembollerin hiçbirine ihtiyaç duyulmadığı sürece, içe aktarma ifadelerini bir dosyanın sonuna bile koyabilirsiniz.
Bir modülde içe aktarma ifadelerinin aşağı taşınmasının, yaptığınız şeyi gizlediğini unutmayın. Bunu, modülünüzün üst kısmına aşağıdaki gibi bir yorum ekleyerek telafi edin:
Genelde bu kötü bir uygulamadır, ancak bazen kaçınılması zordur.