Pardonnez-moi si j'ignore l'évidence ici, mais que se passerait-il si vous enregistrez un appel à super dans une variable et l'utilisez plus tard.

Voici une partie d'une définition de classe pour vous montrer ce que je veux dire.

class CaselessDict(dict):

    def __init__(self, *args, **kwargs):
        self.super = super(CaselessDict, self) # save super
        self.update(*args, **kwargs)

    def __getitem__(self, key):
        key = self.parsekey(key)
        return self.super.__getitem__(key) # use saved super

Cela est arrivé lorsque j'implémentais cette classe CaselessDict et presque toutes les méthodes y étaient super.

5
qtwtetrt 9 oct. 2011 à 15:41

3 réponses

Meilleure réponse

La chose attendue se produit: self.super contiendra simplement un objet super qui agit exactement comme super(CaselessDict, self).

Le problème avec cette approche est que chaque instance n'a qu'un seul attribut super, donc si vous aviez plus de classes qui utiliseraient cette technique, seule celle assignée à super en dernier fonctionnerait correctement. Aie! Donc, ce n'est généralement pas une bonne idée de le faire. Vous pourriez nommer l'attribut __super pour qu'il soit modifié, mais je vous recommande d'appeler simplement super(CaselessDict, self), comme tout le monde le fait.

Bien sûr, l'herbe est plus verte en Python 3, où un simple appel super() suffit.

4
Petr Viktorin 9 oct. 2011 à 13:24

J'ai eu un cas légitime où je devais faire ce genre de chose, impliquant des classes qui étaient chargées et rechargées dynamiquement. Voici un extrait qui charge un module "a" contenant la classe A, et en crée et l'instance:

>>> import imp
>>> m = imp.find_module("a")
>>> a = imp.load_module("a", *m)
>>> a.A
<class 'a.A'>
>>> aobj = a.A()
>>> aobj.__class__
<class 'a.A'>

Maintenant, si je réimporte "a", voyez ce qui se passe si j'appelle isinstance avec l'aobj créé précédemment:

>>> a = imp.load_module("a", *m)
>>> print a.A
<class 'a.A'>
>>> isinstance(aobj, a.A)
False

En ce qui concerne super, c'est qu'à partir de Python 2.6, super(AClass,self) a ajouté la vérification pour s'assurer que l'auto-référence était bien une instance de AClass. Dans mon cas, j'ai utilisé super dans une méthode "A", mais une fois le module "a" réimporté et la classe "A" redéfinie, mes super références ne fonctionnaient plus! La classe a.A avait changé pour quelque chose que mes instances existantes de a.A n'étaient plus, et donc super(a.A, self) commencerait à lever TypeErrors. Pour résoudre ce problème, j'ai essentiellement fait ce que l'OP a fait: dans __init__, j'enregistre une référence à super dans une variable d'instance, qui est ensuite utilisée dans d'autres méthodes pour appeler des méthodes de classe de base.

Voici mon blog complet (et peut-être un peu décousu) publier.

0
PaulMcG 9 oct. 2011 à 14:47

L'univers va exploser. Non, rien de mal ne devrait se produire, même si ce n'est pas l'usage habituel. Pour mémoire, en Python 3, vous pouvez simplement utiliser super().foo(...), il est donc pratiquement inutile de le faire.

0
Cat Plus Plus 9 oct. 2011 à 11:59