SORU
26 EKİM 2013, CUMARTESİ


Neden Python 3.x'In super() sihirli?

Python 3'te.x, 42* *bağımsız değişken olmadan çağrılabilecek:

class A(object):
    def x(self):
         print("Hey now")

class B(A):
    def x(self):
        super().x()
>>> B().x()
Hey now

Bu işi yapmak için biraz zaman derleme büyü yapılır, bir sonucu olan aşağıdaki kod super_ super rebinds () başarısız

super_ = super

class A(object):
    def x(self):
        print("No flipping")

class B(A):
    def x(self):
        super_().x()
>>> B().x()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in x
RuntimeError: super(): __class__ cell not found

Neden super() derleyici yardımı olmadan çalışma zamanında üst çözemediğimiz? Bu davranış, ya da bunun altında yatan sebep, tedbirsiz bir programcı ısırabilir pratik durumlar var mı?

... ve bir yan soru: vb fonksiyonları yöntemleri Python başka örnekleri var. farklı bir isimle yeniden birleştirme kırık olabilir?

CEVAP
26 EKİM 2013, CUMARTESİ


super() yeni sihirli davranış D. R. Y. (Kendini Tekrar Etme) prensibi ihlal önlemek için, PEP 3135 bakın eklendi. Açıkça bir küresel de super() kendisi ile aynı keşfetti yeniden bağlanma sorunları eğilimli olarak başvurarak sınıfın adı:

class Foo(Bar):
    def baz(self):
        return super(Foo, self).baz()   42

Spam = Foo
Foo = something_else()

Aynı sınıf adı rebinds dekoratör yeni bir nesne döndürür sınıf dekoratörler kullanarak için 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

super() __class__ sihirli hücre kibarca bu konuları özgün sınıf nesnesi için erişim vererek sidesteps.

KEP initially envisioned super becoming a keyword ve bir cep mevcut sınıf aramak için kullanma fikri 45* *kim Guido tarafından başlatıldı. Kesinlikle, bir kelime yapmak için fikir first draft of the PEP parçasıydı.

Ancak, aslında, 47**, bunun yerine geçerli uygulama öneren kim kendini Guido. 48* o *:

Benim yama Ara bir çözüm kullanır: __class__ihtiyacınız olduğunu varsayar bir değişken 'super' adlı kullandığınızda. Sen (Genel olarak)bu nedenle, supper supper super Yeniden Adlandır ama işe yaramayacak 28**, değişkenler (ama yine de eğer bunu da geçersen işe yarayacak olmadan Eğer bir ilgisiz varsa __class__ ya da gerçek bir sınıf nesne); değişken super işler adında ama bu yöntemi kullanır çalışacak biraz daha yavaş arama yolu hücre değişkenler için kullanılır.

Böylece, sonunda, super bir anahtar kelime kullanarak sağ hissetmedim ilan ve __class__ sihirli bir hücre sağlayan kabul edilebilir bir uzlaşma olduğunu kendisi Guido.

Bu uygulama büyü, örtülü davranışları biraz şaşırtıcı olduğunu kabul ediyorum, ama super() dilde yanlış uygulanan en işlevlerinden biridir. Eğer bu kod hiç bir türetilmiş sınıf you'd end up with an infinite recursion exception deniyordu eğer sadece super(type(self), self) veya super(self.__class__, self) uygulanan çağırmaları internette buldum bir bakın;. En azından super() basitleştirilmiş çağrı, argümanlar olmadan önlerbusorun.

Senin yöntemi olarak değiştirildi super_; sadece başvuru __class__deve yine işe yarayacak. Hücre super() kullanırsanız oluşturuluryasenin yöntemi: __class__ kullanın

>>> 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

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • 99being99

    99being99

    2 EYLÜL 2008
  • esnathesinger

    esnathesinge

    6 NİSAN 2009
  • Liam Underwood

    Liam Underwo

    19 Mayıs 2009