2012-03-29 3 views
3

Ie, wenn ich eine Klasse MyClass habe, und ich super (MyClass). init, wie kann ich sagen, welche Klasse init wird eigentlich aufgerufen werden?In Python, wie kann ich sagen, welche Klasse ein Superobjekt einwickelt?

Einige Code zu veranschaulichen:

class MyClass(OtherClass, ThirdClass): 
    def __init__(self): 
     mySuper = super(MyClass) 
     if mySuper == SomeClass: 
      # doesn't work - mySuper is a super object (not a normal class object) 
      pass 
     if mySuper.__init__ == SomeClass.__init__: 
      # doesn't work - mySuper.__init__ is a super-method-wrapper object 
      pass 
     if mySuper.__thisclass__ == SomeClass: 
      # doesn't work - __thisclass__ is set to be MyClass, not the "parent" class 
      pass 

Irgendwelche Ideen?

+0

Wenn Sie Mehrfachvererbung verwenden, können Sie '* args' und' ** kwargs' an die Superklasse ''__init__' übergeben, die die gewünschten Argumente extrahieren kann (indem Sie sie als Argumente benennen). ** Warum ** würdest du das machen wollen? – Darthfett

Antwort

1

können Sie die verpackte Klasse extrahieren

mro = my_super.__self_class__.mro() 
wrapped_class = mro[mro.index(my_super.__thisclass__) + 1] 

Das sieht komplex, aber ich denke auch, es ziemlich sinnlos ist, dies zu tun.

Bearbeiten: Ich habe gerade festgestellt, dass Sie self nicht an super() übergeben. Für diesen Fall könnten Sie verwenden

Die Frage, die bleibt, ist: Warum möchten Sie dies tun?

+0

Warum? - Ich habe eine Klassenkette mit Mehrfachvererbung. Die Konstruktoren unterstützen alle Kwargs. Das Problem ist, dass ich eine Klasse habe, die in einigen Mros einen Super hat, der "Objekt" ist, und in anderen Mro's einen anderen meiner Klassen hat, weil es super ist. Früher habe ich tun, um nur immer: Super (MyClass, Selbst-) .__ init __ (** kwargs) ... aber dies wirft nun eine deprecation Warnung, dass args/kwargs ... btw nicht nehmen widersprechen. .. nicht sicher, was die Etikette auf "alten" Fragen ist - Ich weiß auf vielen Foren, alte Threads wiederbeleben wird abgeraten. Wie wäre es, Antworten auf alte Fragen zu markieren? –

+0

@PaulMolodowitch: Der richtige Weg, um dies zu handhaben ist, dass jeder Konstruktor eine Signatur wie '__init __ (self, x, y, ** kwargs)' verwendet, um die Argumente, die er selbst verwendet, zu entfernen und '** kwargs zu übergeben 'auf den 'Super'-Konstruktor. Auf diese Weise ist '** kwargs' leer und es wird keine Fehlermeldung angezeigt. Sieh Raymond Hettingers "Python's super()", "Super" oder ähnliches für Details - Ich bin mir sicher, dass Google den Link finden wird. –

+0

true, und das ist im Allgemeinen die Art, wie ich die Dinge handhaben möchte ... in diesem speziellen Fall, glaube ich, hatte ich es mit einer existierenden Codebasis zu tun mit einer Klasse, die ein benutzerdefiniertes "__init__" UND benutzerdefiniertes "__new__" hatte. und war nicht "richtig" Dinge von Args/Kwargs. Um die gesamte Klassenhierarchie so umzuschreiben, dass sie nur "__new__" benutzte und sicherstellte, dass sie kwags platzierte (und sie richtig getestet/debuggte!), War mehr Arbeit, als ich im Moment Zeit hatte ... –