PythonProgramlamaPython Geliştiricisi

İç mekanizma üzerinden **Python**, iç içe fonksiyonlar için nasıl sözel kapsamı uygular ve **nonlocal** ifadesi, kapsayıcı kapsamda tanımlanan değişkenleri değiştirmeye izin vermek için **cell objelerini** nasıl manipüle eder?

Hintsage yapay zeka asistanı ile mülakatları geçin

Soruya Cevap

Python, iç içe fonksiyonlar ile kapsayıcı kapsamlar arasında aracılar olarak hareket eden cell objeleri içeren bir mekanizma aracılığıyla sözel kapsamı uygular. Bir iç fonksiyon, dış bir kapsamdan bir değişkeni referans aldığında, derleyici onu serbest bir değişken olarak işaretler (co_freevars içinde depolanır) ve kapsayıcı fonksiyon, bu değişkenin değerini standart yerel değişken alanı yerine bir cell objesi içinde depolar. nonlocal anahtar kelimesi, yorumlayıcıya yeni bir yerel bağlama oluşturmaktansa, bu mevcut cell objesine ismin çözümlemesini talep eder, böylece iç kapsam dış kapsamla aynı bellek konumuna okuma ve yazma işlemleri gerçekleştirebilir.

Hayattan Bir Durum

Bize, küreselleşen ad alanını kirletmeden veya tam bir sınıf hiyerarşisi oluşturmadan, bir veri işleme hattında sanitize edilmiş kayıtların sayısını süren hafif bir denetim günlüğü uygulamamız gerekti. Zorluk, sayacın durumunun iç günlüğe alma işlevine olan çağrılar arasında korunmasını sağlamak, aynı zamanda onu oluşturan fabrika fonksiyonu içinde kapsüllü kalmaktı.

Bir çözüm olarak, günlüğü oluşturan ID'siyle anahtarlanan sayacı depolamak için küresel bir sözlük kullanmayı düşünmüştük. Bu yaklaşım basitlik sundu ve durumu dışarıdan incelemeye izin verdi, ancak küresel ad alanının kirlenmesine yol açtı ve tüm uygulama boyunca iş parçacığı güvenliğini sağlamak için karmaşık kilitleme mekanizmaları gerektirdi. Ek olarak, bu, diğer modüllere uygulama detaylarını açarak kapsüllemeyi bozdu.

Başka bir yaklaşım, sayacı tutmak için bir örnek özelliğine sahip özel bir sınıf oluşturmaktı. Bu uygun kapsülleme ve tanıdık nesne yönelimli anlamsal sundu, ancak temelde tek bir işlevsel yardımcı için gereksiz olan bol miktarda kod ekledi ve örnek oluşturma sürecinin yüksek frekanslı günlüğe alma işlemleri için fazla olduğu düşünüldü; çünkü binlerce kez oluşturulabiliyordu.

Seçilen çözüm, sayacı kapsayıcı kapsamda bir cell objesine bağlamak için nonlocal bildirimini kullanan bir kapama (closure) sağladı. Bu yaklaşım, sınıf yükü olmadan temiz işlevsel kapsülleme sağladı, durumun kapalı kalmasını sağladı ve Python'un optimize edilmiş hücre serbest bırakma mekanizmasını kullandı; bu, yerel değişkenlerden biraz daha yavaş olmasına rağmen, I/O işlemlerine kıyasla önemsizdi. Sonuç olarak, sınıf tabanlı yaklaşıma kıyasla bellek aşımında %40 bir azalma sağlandı ve küresel durum çatışmaları ortadan kaldırıldı.

Adayların Genellikle Gözden Kaçırdığı

Dış bir kapsamdan bir değişkene atama yapıldığında, neden nonlocal anahtar kelimesi olmadan dış olanı değiştirmek yerine yeni bir yerel değişken oluşturur?

Python'da, atama bir ifade olup varsayılan olarak mevcut yerel kapsam içinde bir ismi bir değere bağlar. Derleyici, bir iç fonksiyonda atama ile karşılaştığında, değişkenin o fonksiyona yerel olduğunu belirler; aksi belirtilmedikçe. nonlocal olmadan, iç fonksiyon kendi f_locals sözlüğünde yeni bir giriş oluşturur, dış değişkeni tamamen gölgeler. nonlocal bildirimi, derleyiciyi değişkeni kapsayıcı kapsamda oluşturulan cell objesi referansı olarak ele alması için zorlar ve paylaşılan bellek konumuna okuma ve yazma erişimi sağlar.

Kapsam çözümlemesi açısından nonlocal ve global arasındaki temel fark nedir?

Her iki anahtar kelime de atamanın işlendiği kapsamı değiştirirken, global isim çözümlemesini modül seviyesindeki küresel ad alanıyla sınırlar ve herhangi bir araya giren kapsayıcı fonksiyon kapsamlarını atlar. Buna karşılık, nonlocal özel olarak mevcut yerel kapsamı atlar ve ismin ilişkilendirildiği en yakın cell objesini bulmak için kapsayıcı fonksiyon tanımlarında (ancak modül küresel değişkenlerinde değil) araştırma yapar. Bu, nonlocal'in modül düzeyinde değişkenleri değiştirmek için kullanılamayacağı ve global'in iç içe geçen fonksiyonlar içinde değişkenleri göremeyeceği anlamına gelir; bu değişkenler, o dış fonksiyonlarda da açıkça küresel olarak belirtilmedikçe.

Birden fazla iç içe fonksiyon, aynı durumu nasıl paylaşır ve bu hücreler ne zaman tahsis edilir?

Bir dış fonksiyon, dış kapsamdan aynı değişkeni referans alan birden fazla iç fonksiyon tanımladığında, Python derleyicisi o değişken için dış fonksiyonun çerçevesinde tek bir cell objesi oluşturur. Tüm iç fonksiyonlar, __closure__ tuplelarında bu aynı cell objesine bir referans alır. Bu hücreler, dış fonksiyon çalıştığında (kod derlendiğinde değil) çalışma zamanında tahsis edilir ve herhangi bir iç fonksiyon (veya onlara referans) var olduğu sürece kalır. Bu paylaşılan cell objesi, farklı iç fonksiyonların kapsanan değişkenin birbirlerinin değişikliklerini gözlemlemesine olanak tanır ve sınıf olmaksızın örnek değişkenleri benzeri bir paylaşılan durum mekanizması oluşturur.