2016-01-02 28 views
5

Kısa bir süre önce, derleme sırasında bir sınıf için symbol table entry'u görüntüleyerek CPython kaynak koduna adım atıyordum.__class__ üzerindeki kapanışlar

Ben typedef struct _symtable_entry yapı için aşağıdaki girişi çarptı:

[-- other entries --] 
unsigned ste_needs_class_closure : 1; /* for class scopes, true if a 
             closure over __class__ 
             should be created */ 
[-- other entries --] 

Gerçekten bunu anlamak gibi olamaz ve aslında ste_needs_class_closure == 1 ayarlayan piton kodu örneği bulamıyor.

class foo: 
    y = 30 
    def __init__(self): 
     self.x = 50 
    def foobar(self): 
     def barfoo(): 
      print(self.x) 
      print(y) 
     return barfoo 

bunun olacağını ümit Ama yürütür bile, yürütme sırasında ste_needs_class_closure değeri 0 olup 1: bir başka başarısız girişimden arasında, aşağıdaki çalıştılar.

Bu değeri gerçekten değiştiren işlev, çok fazla yardımcı olmayan drop_class_free şeklindedir. Ne yazık ki, bunu iltifat eden hiç bir yorumu yok.

Aslında bir yorum ile analyze_block kullanılır:

/* Check if any local variables must be converted to cell variables */ 

Bir kavram olarak anlayabiliyorum ama olur bir örnek bulamıyorum hangi.

the changelog for Python 3.4 numaralı telefonu aramayı denedim, bu üyenin ilk göründüğü sürümde ancak başvuru bulunamadı.

Yani, herkes bir sınıfın yerel değişkenleri hücre değişkenlerine dönüştürülürken, __class__ üzerinden kapanışının ne anlama geldiğini açıklayabilir mi? İdeal olarak, bu davranışı gerçekten yürütme sırasında görünür yapan bir örnek harika olur.

cevap

2

Github’s blame view for that line of code o Issue #12370 başvuran this commit, içinde eklendiğini gösteriyor: __class__ kapatılması müdahale sınıf organları engelleyin. hata raporundan

Bunu düzeltmek için çalışıyordu sorun türüne bir örnektir:

Python 3 Aşağıdaki kod baskılar False yılında

super() kullanımı __class__ açıklayıcı olmaya neden oldu çünkü sınıf ad alanında ihmal edildi. super kullanımını kaldırın ve True yazdırır.

class X(object): 
    def __init__(self): 
     super().__init__() 

    @property 
    def __class__(self): 
     return int 

print (isinstance(X(), int)) 

(bu kod new super() kullandığını unutmayın.)

da hata raporundan yama işlevselliği, ilgili:

class C(A, B, metaclass=meta): 
    def f(self): 
     return __class__ 

böyle yaklaşık derlenmiş için::

yama temelde şu class deyimi neden olur

def _outer_C(*__args__, **__kw__): 
    class _inner_C(*__args__, **__kw__): 
     def f(self): 
      return __class__ 
    __class__ = _inner_C 
    return _inner_C 
C = _outer_C(A, B, metaclass=meta) 

… Daha sonraki tartışmalara rağmen Son yamada __args__ ve __kw__ işlemlerinin değişmiş olabileceğini unutmayın.