2011-08-12 15 views
29

Python sınıfımın __getattribute__ ve __setattr__ yöntemlerini geçersiz kılmak istiyorum. Kullanım durumum normal olanıdır: Kullanmak istediğim birkaç özel ada sahip olduğum ve başka bir şey için varsayılan davranışı istiyorum. __getattribute__ için, varsayılan davranışı yalnızca AttributeError'u yükselterek isteyebileceğim gibi görünüyor. Ancak, __setattr__'da nasıl aynı şeyi yapabilirim? Burada, "A", "B" ve "C" değişken alanları olan bir sınıfı uygulayan önemsiz bir örnek var.Python'daki yeni stil sınıflarında __setattr__ ve __getattribute__ öğelerini düzgün bir şekilde nasıl geçersiz kılarsınız?

class ABCImmutable(SomeSuperclass): 
    def __getattribute__(self, name): 
     if name in ("A", "B", "C"): 
      return "Immutable value of %s" % name 
     else: 
      # This should trigger the default behavior for any other 
      # attribute name. 
      raise AttributeError() 

    def __setattr__(self, name, value): 
     if name in ("A", "B", "C"): 
      raise AttributeError("%s is an immutable attribute.") 
     else: 
      # How do I request the default behavior? 
      ??? 

Soru işaretlerinin yerine ne geçer? Eski stil sınıfları ile yanıt görünüşte self.__dict__[name] = value idi, ancak belgeler bunun yeni stil sınıfları için yanlış olduğunu gösteriyor.

+0

"belgeler, yeni stil sınıfları için bunun yanlış olduğunu gösterir" ... ve yeni stil sınıfları için neyin doğru olduğunu göstermedi mi? – Gerrat

+0

Niçin adlandırılmış alanlarınızı sadece set-only özellikler olarak kullanmıyorsunuz? – katrielalex

+2

Değişkenlik, __setattr__ için önemsiz bir örnek kullanım örneğiydi. Benim gerçek kullanımım biraz daha karmaşık. Sınıfım dict'ten miras alır, ancak buna ek olarak, belirli özel anahtarların (çalışma zamanında belirlenir), object ['key'] 'yerine' object.key 'erişilebilir. Muhtemelen çalışma zamanı yansıması veya bir şey kullanarak özellikleri olarak ekleyebilirsiniz ama '__getattr__' ve' __setattr__' kullanmak daha kolaydır ve performans özellikle kritik değildir. –

cevap

28

Size __getattribute__ için varsayılan davranışına geri düşmek nasıl AttributeErrordeğil olduğunu yükselterek

Python 2'de
super(ABCImmutable, self).__setattr__(name, value) 

veya 3.

Ayrıca Python

super().__setattr__(name, value) 

var . Sen AttributeError Raising Python 3.

return super(ABCImmutable, self).__getattribute__(name) 
Python 2

veya

return super().__getattribute__(name) 

ile varsayılan geri düşmek varsayılan işlemeyi atlar ve __getattr__ gider, ya da sadece bir AttributeError üretir __getattr__ varsa çağrı kodu.

Customizing Attribute Access belgelerine bakın.

+3

Kapatın, ancak ikinci "kendine" ihtiyacınız yok. Bunu şu şekilde adlandırırdınız: super (ABCImmutable, self) .__ setattr __ (isim, değer) Aksi takdirde "beklenen 2 argüman, ancak üç tane" istisnası alırsınız. – Dave

5

SomeSuperclass.__setattr__(self, name, value)?

+0

"Süper" bir yere bir aramaya ihtiyacım yok mu? En azından genel davada mı? –

+0

@Ryan Thompson 'SomeSuperclass' yerine 'super() 'işlevini kullanabileceğime gayet eminim fakat bu Python 3'e özgü olup olmadığını bulmaya çalışıyorum. –

+0

@Ryan Thompson [Python 2 örneklerine bakma Raymond Hettinger'ın "Python'un süper() süper olduğu için!" post] (http://code.activestate.com/recipes/577721-how-to-use-super-effectively-python-27-version/) 'süper (ABCImmutable, self) .__ setattr__ gibi görünüyor (benlik, isim, değer) 'Python 2'de. Cevabımı, doğru işleyiş olduğunu düşündüğüm şeyle güncelleyeceğim. –

İlgili konular