Soru Pek çok argümanla Python sınıfının kurucusunu nasıl geçersiz kılarsınız?


Diyelim ki, sınıf Bar'ı genişleten bir sınıfım var. Ve Foo’nun yapıcısını biraz geçersiz kılmak istiyorum. Bar’ın kurucularının nasıl bir işaret olduğunu bile bilmiyorum. Bunu yapmanın bir yolu var mı?

Anlamadıysanız, aşağıdakileri kastediyorum:

class Bar:
   def __init__ (self, arg1=None, arg2=None, ... argN=None):
      ....


class Foo (Bar):
    #Here i just want add additional parameter to constructor, but don't want to know anything about Bar's other parameters (arg1, arg2..., argN)
    def __init__ (self, my_new_arg=None, ??? )
       self.new_arg = my_new_arg
       Bar.__init__(self, ??? )

Yerine kısa ve zarif bir şey koymak için bir yol var mı? bu kodda? (Belki bazı args / kwargs çeşitleri)


25
2017-11-30 21:44


Menşei


Eğer Foo hakkında çok az şey bilmeli Barneden kaynaklanıyor Bar? Yani, verilen teknik yararlı bir zaman tasarrufu, ama ... - Karl Knechtel


Cevaplar:


class Parent(object):
    def __init__(self, a, b):
        print 'a', a
        print 'b', b

class Child(Parent):
    def __init__(self, c, d, *args, **kwargs):
        print 'c', c
        print 'd', d
        super(Child, self).__init__(*args, **kwargs)

test = Child(1,2,3,4)

Çıktı:

c 1
d 2
3
b 4

41
2017-11-30 21:55





*args, **kwds @Acorn tarafından sunulan çözüm iyi bir başlangıçtır. *args cevabın bir kısmı). Bu yaklaşım, Python'un makalesinde bir dizi iyileştirme ile sunulmuştur. Süper Üstün Süper.

*args hiyerarşide yeni sınıflar eklemenize izin vermediğinden ve alt sınıfların uyumsuz konumsal argümanlara sahip olabilecek diğer sınıflarla birden fazla miras kullanmasını engelleyemediği için bölüm önerilmez. **kwds Yaklaşım çok daha iyi çalışır çünkü çağrı zincirinin belirli bir düzenini zorlamaz.

Ayrıca, zincirden geçmeden önce geçerli argüman argümanlarının geri kalanından argüman argümanlarını ayırmak ve kaldırmak için adlandırılmış argümanları kullanabilirsiniz.

class Bar(object):
   def __init__(self, arg1=None, arg2=None, argN=None):
       print arg1, arg2, argN

class Foo(Bar):
    def __init__(self, my_new_arg=None, **kwds):
       super(Foo, self).__init__(**kwds)
       self.new_arg = my_new_arg
       print my_new_arg

f = Foo(my_new_arg='x', arg2='y')

Her yöntemin ihtiyaç duyduğu argümanları çıkarması önemlidir çünkü .__ init__ nesne hiç bir argüman beklemez.

Son bir not, eğer kullanacaksan SüperEn üst sınıfınızın yeni stil olduğundan emin olun (örn. nesne veya başka bir yerleşik tip).


11
2017-11-30 22:59