super()
KURU (Kendinizi Tekrarlama) ilkesini ihlal etmemek için yeni büyü davranışı eklendi, bkz. PEP 3135 . Sınıfı bir küresel olarak referans alarak açık bir şekilde adlandırmak zorunda kaldığınızda, super()
kendi keşfettiğiniz aynı yeniden bağlama sorunlarına da eğilimlidir :
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
Spam().baz() # liable to blow up
Aynısı, dekoratörün sınıf adını yeniden hatırlatan yeni bir nesne döndürdüğü sınıf dekoratörleri kullanmak için de geçerlidir:
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
Sihirli super()
__class__
hücre, orijinal sınıf nesnesine erişmenizi sağlayarak bu sorunları güzelce kaldırır.
PEP, başlangıçta super
bir anahtar kelime olmayı öngören Guido tarafından başlatıldı ve mevcut sınıfa bakmak için bir hücre kullanma fikri de onun oldu . Elbette, onu bir anahtar kelime yapma fikri PEP'in ilk taslağının bir parçasıydı .
Bununla birlikte, aslında Guido , anahtar kelime fikrinden 'çok büyülü' olarak uzaklaştı ve bunun yerine mevcut uygulamayı önerdi. O için farklı bir ad kullanarak tahmin super()
bir sorun olabilir :
Düzeltme ekim bir ara çözüm kullanıyor: __class__
adlı bir değişkeni kullandığınızda ihtiyacınız olduğunu varsayar 'super'
. Bu nedenle, (genel olarak) yeniden adlandırmak super
için supper
ve kullanım supper
ancak super
, bu bağımsız değişken olmadan çalışmaz (ama olacak yine iş bunu başarılı olursa, ya
__class__
ya da gerçek sınıf nesnesi) adında ilgisiz bir değişkeniniz varsa super
işler işe yarar ancak yöntem, hücre değişkenleri için kullanılan biraz daha yavaş çağrı yolunu kullanır.
Böylece, sonunda, bir super
anahtar kelime kullanmanın doğru olmadığını ve sihirli bir __class__
hücre sağlamanın kabul edilebilir bir uzlaşma olduğunu ilan eden Guido'nun kendisi oldu.
Uygulamanın sihirli, örtük davranışının biraz şaşırtıcı olduğunu, ancak super()
dilde en yanlış uygulanan işlevlerden biri olduğunu kabul ediyorum . Sadece internette bulunan tüm yanlış uygulamalara super(type(self), self)
veya super(self.__class__, self)
çağrılara bir göz atın ; bu kodlardan herhangi biri türetilmiş bir sınıftan çağrılmış olsaydı, sonsuz bir özyineleme istisnasıyla karşılaşırsınız . En azından basitleştirilmiş super()
çağrı, argüman olmadan, bu problemden kaçınır .
Yeniden adlandırılmış gelince super_
; Sadece referans __class__
senin yöntemde de ve tekrar çalışacağız. Yönteminizdeki super
veya __class__
adlarına başvurursanız hücre oluşturulur :
>>> super_ = super
>>> class A(object):
... def x(self):
... print("No flipping")
...
>>> class B(A):
... def x(self):
... __class__ # just referencing it is enough
... super_().x()
...
>>> B().x()
No flipping