2016-04-02 15 views
1

Adıyla bir super() nesnesinde bir yöntem bulmam gerekiyor. Bu, "nokta operatörü" gösterimini kullanırken çalışır: super(self.__class__,self).p. Bununla birlikte, bunu dinamik olarak yapmam gerekiyor, super(self.__class__,self)["p"] gibi bir şey çalışmıyor.Bir super() nesnesinde dinamik yöntem çözünürlüğü

__getattr__'u kullanmayı denedim, ancak süper nesne bu yönteme sahip değil. Ve super(self.__class__,self).__getattribute__("p"), super().p yerine self.p döndürür.

Doğru ve zarif bir şekilde nasıl yapılır? Örneğin

:

class A(object): 
    def p (self): 
     skip 

class B(object): 
    def p (self): 
     skip 

class AB (A,B): 
    def p (self): 
     skip 

ab = AB() 
o = super(ab.__class__, ab) 

print dir(o) 
print o.__getattribute__("p").__code__ 
print o.p.__code__ 

Bu kod çıkışları:

['__class__', '__delattr__', '__doc__', '__format__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__ 
', '__self__', '__self_class__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__thisclass__'] 
<code object p at 000000000205f2b0, file "b.py", line 10> # AB.p 
<code object p at 0000000000361cb0, file "b.py", line 2> # A.p 
+1

... ne? Neyi başarmaya çalıştığınıza dair daha az soyut bir örnek verebilir misiniz? Ayrıca, "self .__ class__" ile "süper" arasında geçiş yapmak kötü bir fikirdir (bkz. Http://stackoverflow.com/q/4235078/3001761). – jonrsharpe

+0

@jonrsharpe Sınıfın içinde self .__ class__ kullanmıyor. Herhangi bir soruna yol açmayacak. – Bharel

+0

@Bharel aslında, gerçekten çok yararlı olan "snip" lerden olup olmadıklarını göremiyoruz. Ama 'AB' yerine 'ab .__ class__' kullanmak garip görünüyor. – jonrsharpe

cevap

2

aradığınız ne getattr() olduğunu. Bu çalışır:

>>> getattr(o, "p") 
<bound method A.p of <__main__.AB object at 0x0000000000AA8160>> 

doğrudan __getattribute__() kullanarak, sarma super() nesneye yapar kaybederler. Metodları veya diğer özellikleri almak için her zaman getattr()'u kullanmalısınız. Genel olarak, başka seçenekler varsa, doğrudan __dunder__ yöntemlerine gitmek önerilmez.

+0

Kesinlikle, çok teşekkürler. Bunu nasıl yapacağımı anlayarak çok fazla zaman harcadım, ama başarılı olamadım. – xarx

İlgili konular