Python super () ile __init __ () y├Ântemlerini anlama [duplicate]


Al─▒nan cevaba git


Bu sorunun zaten burada bir cevab─▒ var:

Kullan─▒m─▒n─▒ anlamaya ├žal─▒┼č─▒yorum super() . G├Âr├╝n├╝┼č├╝nden bak─▒ld─▒─č─▒nda, her iki alt s─▒n─▒f da olu┼čturulabilir, gayet iyi.

A┼ča─č─▒daki 2 ├žocuk s─▒n─▒f─▒ aras─▒ndaki ger├žek fark─▒ bilmek istiyorum.

 class Base(object):
    def __init__(self):
        print "Base created"

class ChildA(Base):
    def __init__(self):
        Base.__init__(self)

class ChildB(Base):
    def __init__(self):
        super(ChildB, self).__init__()

ChildA() 
ChildB()
 

2345









Cevap say─▒s─▒n─▒ say: 7






super() a├ž─▒k├ža iyi olabilecek ana s─▒n─▒fa at─▒fta bulunmaman─▒z─▒ sa─člar. Ancak as─▒l avantaj, her t├╝rl├╝ e─členceli ┼čeyin olabilece─či ├žoklu kal─▒t─▒mla geliyor . Hen├╝z yapmad─▒ysan─▒z , standartlar ├╝zerinde s├╝per olanlar─▒ g├Âr├╝n .

S├Âzdiziminin Python 3.0'da de─či┼čti─čini unutmay─▒n : super().__init__() Bunun yerine super(ChildB, self).__init__() IMO'nun biraz daha iyi oldu─čunu s├Âyleyebilirsiniz . Standart dok├╝manlar ayr─▒ca olduk├ža a├ž─▒klay─▒c─▒ olan super () kullan─▒m k─▒lavuzuna da at─▒fta bulunur .


1703


2009-02-23





Anlamaya ├žal─▒┼č─▒yorum super()

super Kullanmam─▒z─▒n nedeni, i┼čbirlik├ži ├žoklu kal─▒t─▒m─▒n kullanabilece─či alt s─▒n─▒flar─▒n, Y├Ântem ├ç├Âz├╝n├╝rl├╝k S─▒ras─▒ndaki (MRO) do─čru sonraki ├╝st s─▒n─▒f i┼člevini ├ža─č─▒rmas─▒d─▒r.

Python 3'te ┼č├Âyle diyebiliriz:

 class ChildB(Base):
    def __init__(self):
        super().__init__() 
 

Python 2'de ┼ču ┼čekilde kullanmam─▒z gerekiyor:

 super(ChildB, self).__init__()
 

S├╝per olmadan ├žoklu miras kullanma kabiliyetiniz s─▒n─▒rl─▒d─▒r:

 Base.__init__(self) # Avoid this.
 

A┼ča─č─▒da daha detayl─▒ a├ž─▒klayaca─č─▒m.

ÔÇťBu kodda asl─▒nda ne fark var ?:ÔÇŁ

 class ChildA(Base):
    def __init__(self):
        Base.__init__(self)

class ChildB(Base):
    def __init__(self):
        super(ChildB, self).__init__()
        # super().__init__() # you can call super like this in Python 3!
 

Bu kodda temel fark sen dolaylama katman─▒ elde ediyoruz __init__ ile super sonraki s─▒n─▒f en belirlemek i├žin cari s─▒n─▒f─▒n─▒ kullan─▒r, hangi __init__ MRO i├žinde aranacak.

Bu fark─▒ , Python'da 's├╝per' nas─▒l kullan─▒l─▒r? Hangi g├Âsteriyor ba─č─▒ml─▒l─▒k enjeksiyon ve kooperatif ├žoklu miras .

Python olmasayd─▒ super

─░┼čte asl─▒nda e┼čde─čerde olan kod super (C'de nas─▒l uyguland─▒─č─▒, baz─▒ kontrol ve geri d├Ân├╝┼č davran─▒┼člar─▒ ve Python'a nas─▒l ├ževrildi─či):

 class ChildB(Base):
    def __init__(self):
        mro = type(self).mro()             # Get the Method Resolution Order.
        check_next = mro.index(ChildB) + 1 # Start looking after *this* class.
        while check_next < len(mro):
            next_class = mro[check_next]
            if '__init__' in next_class.__dict__:
                next_class.__init__(self)
                break
            check_next += 1
 

Biraz daha yerli Python gibi yaz─▒lm─▒┼čt─▒r:

 class ChildB(Base):
    def __init__(self):
        mro = type(self).mro()
        for next_class in mro[mro.index(ChildB) + 1:]: # slice to end
            if hasattr(next_class, '__init__'):
                next_class.__init__(self)
                break
 

Biz olmasayd─▒ super nesneyi, her yerde bu manuel kod yazmak olurdu (veya yeniden olu┼čturun!) Biz Y├Ântem ├ç├Âz├╝n├╝rl├╝k Sipari┼č d├╝zg├╝n bir sonraki y├Ântemi ├ža─č─▒rmak sa─člamak i├žin!

S├╝per, Python 3'te, hangi y├Ântem ve s─▒n─▒ftan ├ža─čr─▒ld─▒─č─▒ a├ž─▒k├ža s├Âylenmeden bunu nas─▒l ger├žekle┼čtirir?

├ça─č─▒ran y─▒─č─▒n ├žer├ževesini al─▒r ve s─▒n─▒f─▒ bulur (dolayl─▒ olarak yerel bir serbest de─či┼čken olarak saklan─▒r __class__ , b├Âylece arama i┼člevini s─▒n─▒f ├╝zerinde kapat─▒r) ve bu fonksiyona ili┼čkin ilk arg├╝man─▒ g├Âsterir. Y├Ântem ├ç├Âz├╝mleme S─▒ras─▒ (MRO) kullan─▒lacak.

O MRO i├žin ilk arg├╝man gerektirdi─činden, kullan─▒larak super statik y├Ântemlerle m├╝mk├╝n de─čildir .

Di─čer cevaplar─▒n ele┼čtirileri:

super () a├ž─▒k├ža temel s─▒n─▒fa at─▒fta bulunmaman─▒z─▒ sa─člar, bu ho┼č olabilir. . Ancak as─▒l avantaj, her t├╝rl├╝ e─členceli ┼čeyin olabilece─či ├žoklu kal─▒t─▒mla geliyor. Hen├╝z yapmad─▒ysan─▒z, standartlar ├╝zerinde s├╝per olanlar─▒ g├Âr├╝n.

Olduk├ža el dalgal─▒ ve bize pek bir ┼čey anlatm─▒yor, ancak super as─▒l konu ana s─▒n─▒f─▒ yazmaktan ka├ž─▒nmak de─čil. Ama├ž, y├Ântem ├ž├Âz├╝mleme s─▒ras─▒na (MRO) g├Âre s─▒radaki y├Ântemin ├ža─čr─▒lmas─▒n─▒ sa─člamakt─▒r. Bu ├žoklu kal─▒t─▒mda ├Ânemli hale gelir.

Burada a├ž─▒klayaca─č─▒m.

 class Base(object):
    def __init__(self):
        print("Base init'ed")

class ChildA(Base):
    def __init__(self):
        print("ChildA init'ed")
        Base.__init__(self)

class ChildB(Base):
    def __init__(self):
        print("ChildB init'ed")
        super(ChildB, self).__init__()
 

├çocuklardan sonra aranmak istedi─čimiz bir ba─č─▒ml─▒l─▒k yaratal─▒m:

 class UserDependency(Base):
    def __init__(self):
        print("UserDependency init'ed")
        super(UserDependency, self).__init__()
 

┼×imdi hat─▒rlay─▒n, ChildB s├╝per kullan─▒r, ChildA yapmaz:

 class UserA(ChildA, UserDependency):
    def __init__(self):
        print("UserA init'ed")
        super(UserA, self).__init__()

class UserB(ChildB, UserDependency):
    def __init__(self):
        print("UserB init'ed")
        super(UserB, self).__init__()
 

Ve UserA UserDependency y├Ântemini ├ža─č─▒rmaz:

 >>> UserA()
UserA init'ed
ChildA init'ed
Base init'ed
<__main__.UserA object at 0x0000000003403BA8>
 

Ancak UserB , ChildB kullan─▒r super , yapar !:

 >>> UserB()
UserB init'ed
ChildB init'ed
UserDependency init'ed
Base init'ed
<__main__.UserB object at 0x0000000003403438>
 

Ba┼čka bir cevap i├žin ele┼čtiri

Hi├žbir ko┼čulda, ChildB alt s─▒n─▒f─▒n─▒ ald─▒─č─▒n─▒zda kesinlikle hatalar alaca─č─▒n─▒z i├žin ba┼čka bir cevab─▒n ├Ânerdi─či a┼ča─č─▒dakileri yapmal─▒s─▒n─▒z:

 super(self.__class__, self).__init__() # Don't do this. Ever.
 

(Bu cevap ak─▒ll─▒ca ya da ├Âzellikle ilgin├ž de─čildir, ancak yorumlardaki ve 17'nin ├╝zerinde oyla yap─▒lan ele┼čtirilerin do─črudan ele┼čtirilmesine ra─čmen, cevaplay─▒c─▒ nazik bir edit├Âr sorununu ├ž├Âzene kadar bunu ├Ânermekte ─▒srar etti.)

A├ž─▒klama: Bu cevap, bu ┼čekilde s├╝per arama ├Ânerdi:

 super(self.__class__, self).__init__()
 

Bu tamamen yanl─▒┼čt─▒r. super ├žocuk s─▒n─▒flar─▒ i├žin MRO'da bir sonraki ebeveyni aramam─▒za izin verir (bu cevab─▒n ilk b├Âl├╝m├╝ne bak─▒n). super Alt ├Ârne─čin y├Ânteminde oldu─čumuzu s├Âylerseniz , sat─▒rdaki (muhtemelen bu y├Ântem) sonraki y├Ânteme bakacak ve yinelemeyle sonu├žlanacak, muhtemelen mant─▒ksal bir ba┼čar─▒s─▒zl─▒─ča (cevaplay─▒c─▒ ├Ârne─činde oldu─ču gibi) ya da bir RuntimeError tekrarlama derinli─či ile sonu├žlanacakt─▒r. A┼č─▒ld─▒.

 >>> class Polygon(object):
...     def __init__(self, id):
...         self.id = id
...
>>> class Rectangle(Polygon):
...     def __init__(self, id, width, height):
...         super(self.__class__, self).__init__(id)
...         self.shape = (width, height)
...
>>> class Square(Rectangle):
...     pass
...
>>> Square('a', 10, 10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: __init__() missing 2 required positional arguments: 'width' and 'height'
 

644







Python 3.0+ s├╝r├╝m├╝nde kullanabilece─činiz belirtilmi┼čtir.

super().__init__()

├ça─čr─▒n─▒z─▒ yapmak i├žin, ├Âzl├╝ olan ve ana VEYA s─▒n─▒f adlar─▒na a├ž─▒k├ža ba┼čvurman─▒z─▒ gerektirmeyen, kullan─▒┼čl─▒ olabilir. Sadece Python 2.7 veya alt─▒ i├žin, bu isme duyars─▒z davran─▒┼č─▒ self.__class__ s─▒n─▒f ismi yerine yazarak elde etmenin m├╝mk├╝n oldu─čunu eklemek istiyorum.

 super(self.__class__, self).__init__()
 

Ancak, bu sonlar, bir alt s─▒n─▒fa geri d├Ânebilecek super , s─▒n─▒f─▒n─▒zdan miras alan s─▒n─▒flar─▒ ├ža─č─▒r─▒yor self.__class__ . ├ľrne─čin:

 class Polygon(object):
    def __init__(self, id):
        self.id = id

class Rectangle(Polygon):
    def __init__(self, id, width, height):
        super(self.__class__, self).__init__(id)
        self.shape = (width, height)

class Square(Rectangle):
    pass
 

Burada Square alt s─▒n─▒f─▒ olan bir s─▒n─▒f─▒m var Rectangle . Square Yap─▒c─▒ i├žin Rectangle yeterince iyi oldu─ču i├žin ayr─▒ bir kurucu yazmak istemedi─čimi s├Âyleyin , ancak hangi nedenle olursa olsun bir Kare uygulamak istiyorum, b├Âylece ba┼čka bir y├Ântemi de yeniden uygulayabilirim.

Ben olu┼čtururken Square kullanarak mSquare = Square('a', 10,10) , Python i├žin yap─▒c─▒ ├ža─čr─▒lar─▒ Rectangle ben vermedim ├ž├╝nk├╝ Square kendi yap─▒c─▒. Ancak, yap─▒c─▒ i├žin Rectangle , ├ža─čr─▒ super(self.__class__,self) ├╝st s─▒n─▒f─▒n─▒ d├Ând├╝recek mSquare , bu y├╝zden yap─▒c─▒y─▒ Rectangle tekrar arayacak . Bu, @S_C taraf─▒ndan belirtildi─či gibi, sonsuz d├Âng├╝ b├Âyle olur. Bu durumda, ├žal─▒┼čt─▒rd─▒─č─▒mda super(...).__init__() yap─▒c─▒y─▒ ar─▒yorum Rectangle ama arg├╝man vermedi─čim i├žin bir hata al─▒yorum.


248







Super'in yan etkisi yok

 Base = ChildB

Base()
 

beklendi─či gibi ├žal─▒┼č─▒yor

 Base = ChildA

Base()
 

sonsuz ├Âzyinelemeye girer.


80


2012-11-27





Sadece Python 2.7'ye sahip ... ve super() 2.2 s├╝r├╝m├╝nden beri kullan─▒lmaya ba┼čland─▒─č─▒na inan─▒yorum , ancak super() ebeveynlerden biri sonunda object ( yeni stil s─▒n─▒flar─▒ ) miras alan bir s─▒n─▒ftan miras al─▒rsa arayabilirsin .

┼×ahsen, python 2.7 kodunda oldu─ču gibi BaseClassName.__init__(self, args) , kullan─▒m avantaj─▒ elde edene kadar kullanmaya devam edece─čim super() .


71







Ger├žekten yok. y├Ântemleri ├ža─č─▒rmak i├žin super() MRO'da bir sonraki s─▒n─▒fa bakar (y├Ântem ├ž├Âz├╝mleme s─▒ras─▒, ile eri┼čilir cls.__mro__ ). Sadece ├╝ss├╝ __init__ aramak ├╝ss├╝ ├ža─č─▒r─▒r __init__ . Oldu─ču gibi, MRO'da tam olarak bir madde var - taban. Yani ger├žekten ayn─▒ ┼čeyi yap─▒yorsunuz, ancak daha iyi bir ┼čekilde super() (├Âzellikle daha sonra ├žoklu mirasa girerseniz).


52







Temel fark oldu─čunu ChildA.__init__ ko┼čulsuz arayacak Base.__init__ oysa ChildB.__init__ arayacak __init__ i├žinde bulunabilece─či herhangi bir s─▒n─▒f ChildB i├žinde atas─▒ self atalar─▒n─▒n '─▒n hatt─▒ (bekledi─činizden farkl─▒ olabilir).

Birden ClassC ├žok kal─▒t─▒m kullanan bir eklerseniz :

 class Mixin(Base):
  def __init__(self):
    print "Mixin stuff"
    super(Mixin, self).__init__()

class ChildC(ChildB, Mixin):  # Mixin is now between ChildB and Base
  pass

ChildC()
help(ChildC) # shows that the the Method Resolution Order is ChildC->ChildB->Mixin->Base
 

Daha sonra Base art─▒k ├╝st├╝d├╝r ChildB i├žin ChildC ├Ârnekleri. ┼×imdi bir ├Ârnek olup olmad─▒─č─▒n─▒ super(ChildB, self) g├Âsterecektir . Mixin self ChildC

Sen ekledikten Mixin aras─▒nda ChildB ve Base . Ve bundan faydalanabilirsiniz super()

Bu nedenle, s─▒n─▒flar─▒n─▒z─▒ bir Kooperatif ├çoklu Kal─▒t─▒m senaryosunda kullan─▒labilecek ┼čekilde tasarlad─▒ysan─▒z, kulland─▒─č─▒n─▒z super i├žin ├žal─▒┼čma zaman─▒nda ata kim olaca─č─▒n─▒z─▒ ger├žekten bilmiyorsunuzdur.

S├╝per kabul s├╝per yaz─▒lan ve pycon 2015 Ekteki video , gayet iyi a├ž─▒klar.


28



─░lgili yay─▒nlar


ÔÇťWithÔÇŁ anahtar kelimesi ne i├žin kullan─▒l─▒r? [├žift]

Sahte HttpContext.Current Test Init Y├Ânteminde

-─░nit metodunu Objective-C de ├Âzel yapmak m├╝mk├╝n m├╝d├╝r?

Python super () TypeError'─▒ y├╝kseltir

Spring Controller'da init y├Ântemi (a├ž─▒klama s├╝r├╝m├╝)

Spring @PostConstruct vs. init-method ├Âzniteli─či

S─▒n─▒f yolu kayna─č─▒nda tan─▒mlanan 'entityManagerFactory' ad─▒nda fasulye yarat─▒rken hata olu┼čtu: init y├Ânteminin ├ža─čr─▒lmas─▒ ba┼čar─▒s─▒z oldu

Python ile geni┼čletme - super () Python 3 vs Python 2 ile

iOS5 ├ľyk├╝ Penceresi UIViewController hangi init y├Ânteminin storyboard taraf─▒ndan ├ža─čr─▒l─▒r?

Python'da Kal─▒t─▒m ve Init Y├Ântemi

Etiketle ilgili di─čer sorular [python]


PostmanÔÇÖda olmad─▒─č─▒ zaman JavaScript kodum neden ÔÇť─░stenilen kayna─č─▒n ├╝zerinde 'Eri┼čim Kontrol-─░zin Verme-Orijin' yok 'ba┼čl─▒─č─▒n─▒ g├ÂsteriyorÔÇŁ hatas─▒ al─▒yor?

PHP dizi de─čerine g├Âre silme (anahtar de─čil)

JQuery'ye sorman─▒n resmi yolu, bir ┼čey yapmadan ├Ânce t├╝m resimlerin y├╝klenmesini bekleyin

Statik de─či┼čkenler neden k├Ât├╝ kabul edilir?

Chrome hata ay─▒klay─▒c─▒s─▒nda ÔÇťD─░KKAT: ge├žici ba┼čl─▒klar g├ÂsteriliyorÔÇŁ

Python'da bir liste nas─▒l bo┼čalt─▒l─▒r?

.NET'te mevcut Y─▒─č─▒n ─░zi, istisnas─▒z nas─▒l yazd─▒r─▒l─▒r?

babel-loader jsx S├ÂzdizimiError: Beklenmeyen belirte├ž [kopya]

├ç─▒k─▒┼č URL parametresini al

Kod Yaz─▒m Kurallar─▒ - Adland─▒rma Numaralar─▒