2013-02-26 9 views
2

Je voudrais savoir comment l'héritage fonctionne pour int, list, string et d'autres types immuables.Hériter des types immuables

En fait, je venais de héritez d'une classe comme ceci:

class MyInt(int): 
    def __init__(self, value): 
     ?!?!? 

Je ne peux pas à comprendre, comment puis-je régler la valeur comme elle est définie pour int? Si je ne self.value = value alors ma classe sera utilisé comme ceci:

mi = MyInt(5) 
print(mi.value) # prints 5 

Alors que je veux l'utiliser comme ceci:

mi = MyInt(5) 
print(mi) # prints 5 

Comment puis-je faire cela?

Répondre

7

Vous pouvez sous-classe int, mais parce qu'il est immuable vous devez fournir un .__new__() constructor hook:

class MyInt(int): 
    def __new__(cls, value): 
     new_myint = super(MyInt, cls).__new__(cls, value) 
     return new_myint 

Vous avez besoin d'appeler la base __new__ constructeur pour obtenir votre sous-classe correctement créé.

En Python 3, vous pouvez omettre les arguments super() tout à fait:

class MyInt(int): 
    def __new__(cls, value): 
     new_myint = super().__new__(cls, value) 
     return new_myint 

Bien sûr, cela suppose que vous vouliez manipuler value avant de passer pour super().__new__() ou manipuler new_myint un peu plus avant de revenir; Sinon, vous pouvez également supprimer la méthode __new__ et l'implémenter comme class MyInt(int): pass.

+0

D'accord, c'est plus compliqué que je ne le pensais. Mais je comprends ce que ça fait. Pour python 3, je ne peux pas simplement utiliser 'super()' au lieu de 'super (MyInt, cls)'? Puis-je encore créer des méthodes et/ou d'autres attributs pour cela? –

+0

Cet appel interne '__new__' devrait être' __new __ (cls, value) '. – poke

+0

@PatrikLippojoki Oui, juste 'super()' devrait fonctionner correctement. Et les méthodes personnalisées fonctionnent exactement comme vous le souhaitez. Il suffit de noter que la valeur int réelle est accessible via simplement 'self' dans les méthodes. – poke