Python'da temel sınıfın sınıf yöntemini çağırma


105

Aşağıdaki kodu göz önünde bulundurun:

class Base(object):

    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do(a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')

> $ python play.py  
> In derived! 
> <class '__main__.Base'> msg

Kimden Derived.do, nasıl ararım Base.do?

Normalde superbu normal bir nesne yöntemi ise doğrudan temel sınıf adını veya hatta temel sınıf adını kullanırdım , ancak görünüşe göre temel sınıfta sınıf yöntemini çağırmanın bir yolunu bulamıyorum.

Yukarıdaki örnekte, class yerine class Base.do(a)yazdırmaktadır .BaseDerived


Yanıtlar:


121

Yeni stil bir sınıf kullanıyorsanız (yani object, Python 2'den türetilmişse veya her zaman Python 3'te), bunu şu şekilde yapabilirsiniz super():

super(Derived, cls).do(a)

Bu, print cls, atüretilmiş sınıfa clsayarlanmış olarak, türetilmiş sınıftan temel sınıfın yöntem sürümündeki (yani ) kodu nasıl çağıracağınızdır .


8
uh uh .. nasıl superoldu da sınıf yöntemlerinde de kullanabileceğim hiç aklıma gelmedi .
Sridhar Ratnakumar

bu yalnızca temel nesneden türüyorsa (süper tarafından empoze edilen bir sınırlama nedeniyle) çalışır, değil mi? durum böyle değilse ne yaparsınız?
ars-longa-vita-brevis

Evet, bu sadece yeni stil sınıfları için işe yarar object. (en azından Python 2'de, ancak Py3'te tüm sınıfların yeni stil olduğunu düşünüyorum, IIRC) Aksi takdirde, üst sınıfın Base.do(self, ...)adını sabit kodlamanız gerektiğini düşünüyorum.
David Z

İçeride aynı Derived.do()değil mi? clsDerived
Ray

@Ray Aslında bir Derivedalt sınıfın bir örneğiyse, ancak bir alt sınıfın örneğiyse , evet.
David Z

15

uzun zaman oldu ama sanırım bir cevap bulmuş olabilirim. Bir yöntemi sınıf yöntemi olacak şekilde dekore ettiğinizde, orijinal ilişkisiz yöntem 'im_func' adlı bir özellikte saklanır:

class Base(object):
    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do.im_func(cls, a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')

2
Not: Bu yaklaşım, super () işlevinin çalışmadığı eski tarz sınıflar için işe
Alex Q

2
__func__Python 2.7 ve 3'te de mevcut
dtheodor

-3

Bu benim için çalışıyor:

Base.do('hi')

9
Daha clssonra argüman BaseyerineDerived
Sridhar Ratnakumar

Benim için işe yarayan bu - Ned'in cevabına çok benziyor: Kendinin paintEvent (QPaintEvent) def paintEvent (self, qpntEvent) içeren QGraphicsView'den türetildiği yer: print dir (self) QGraphicsView.paintEvent (self, qpntEvent)
user192127
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.