2011-03-28 16 views
9

Python 3 kaynak kodunda bazı kapsam analizlerini gerçekleştirmeye çalışıyorum ve nonlocal deyim ifadesinin bir sınıf tanımı içinde nasıl çalıştığına bağlı kaldım.Bir sınıf tanımındaki Python olmayan deyim

Anladığım kadarıyla, sınıf tanımı vücudunu yeni bir ad alanı içinde yürütür (bunu dict olarak adlandırın) ve sınıf adını türün (ad, taban, dict) sonucuna bağlar. Yerel olmayan x, yerel dışı kapsamda bir yere bağlı bir değişkene başvurduğu sürece çalışmalıdır. Aşağıdaki kod

def A(): 
    v = 1 
    class B: 
     nonlocal v 
     v = 2 

kimse açıklayabilir

mükemmel çalışır iken

class A: 
    v = 1 
    class B: 
     nonlocal v 
     v = 2 

ama bu

SyntaxError: no binding for nonlocal 'v' found 

başarısız:

Bundan ben derlemek ve çalıştırmak için aşağıdaki kodu bekliyoruz Burada fonksiyon tanımının kapanması ile sınıf tanımı arasındaki fark nedir?

+0

Daha fazla araştırma - son kod örneğinde, A'daki locals() öğesi {v: 1} iken, B içerisindedir: {v: 2, ''__module__'': '' __main__'', ''__locals__'': {...}} – Andyrooger

cevap

10

Sözcüksel belirleme yalnızca işlev ad alanlarına uygulanır, aksi halde bir sınıf içinde tanımlanan yöntemler sınıf düzeyi niteliklerini "görebilecektir" (bu, tasarım gereğince - bu niteliklerin yerine yöntemin içinde self öznitelikleri olarak erişilmesi gerekir).

Sınıf düzeyi değişkenlerinin yöntemlerden gelen referanslarla atlanmasına neden olan aynı sınırlamalar, nonlocal anahtar kelimesinin sihrini çalışmasını da engeller. (global, ancak sözcüksel kapsam belirleme makinelerine bağlı olmadığı için işe yaramıyor)

+0

Teşekkürler, bu mantıklı. Her seviye için aynı şekilde çalışacak bazı çok temel yığınlar olduğunu varsaymıştım. Simüle edilebilen modül belgelerinin farkına varmak fikrimi değiştirdi ama ne olup bittiğini gerçekten anlamadım ya da cevabınıza kadar. – Andyrooger

4

Python, sınıf ve işlev tanımlarını oldukça farklı şekilde ele alır. Örneğin, A.v, A'nın bir değişkeni değil, onun bir özniteliğidir. Bir sınıf tarafından oluşturulan ad alanı, bu nedenle, bir kapsam değildir. Kullanmaya çalıştığınızda, nonlocal'un çalışmadığını şaşırmadım.

+0

Cevabınız için teşekkürler. Böylece, işlev kapsamı, tanımlandığında değil, çalıştırıldığında oluşturulur. Sınıf tanımının gövdesi olduğu için, hemen farklı bir ad alanında yürütüldüğümü farzediyorum, bu sadece bu yürütmenin süresi için bir kapsam oluşturmuyor mu? - Aynı nedenden ötürü bir iç sınıfın bir dış sınıfın özniteliklerine erişemediğini merak ediyorum ... – Andyrooger

+0

Geçici bir kapsam oluşturuyor ama farklı bir * tip * kapsamı var. Derleyici, hangi niteliklerin görülebileceğine karar vermek için farklı kurallar kullanır (hem iç kapsamlardan hem de dışsal kapsamlara başvurmak için). – ncoghlan

İlgili konular