2009-10-28 6 views
5

est donné l'exemple suivant:classe Python avec émulation entier

class Foo(object): 
    def __init__(self, value=0): 
     self.value=value 

    def __int__(self): 
     return self.value 

Je veux avoir une classe Foo, qui agit comme un entier (ou flottant). Donc, je veux faire les choses suivantes:

f=Foo(3) 
print int(f)+5 # is working 
print f+5 # TypeError: unsupported operand type(s) for +: 'Foo' and 'int' 

La première déclaration print int(f)+5 travaille, parce que il y a deux entiers. Le second est en train d'échouer, car je dois implémenter __add__ pour faire cette opération avec ma classe. Donc, pour implémenter le comportement entier, je dois implémenter toutes les méthodes d'émulation d'entier. Comment pourrais-je contourner cela. J'ai essayé d'hériter de int, mais cette tentative n'a pas réussi.

Mise à jour

Héritant de int échoue, si vous souhaitez utiliser un __init__:

class Foo(int): 
    def __init__(self, some_argument=None, value=0): 
     self.value=value 
     # do some stuff 

    def __int__(self): 
     return int(self.value) 

Si vous appelez ensuite:

f=Foo(some_argument=3) 

vous obtenez:

TypeError: 'some_argument' is an invalid keyword argument for this function 

testé avec Python 2.5 et 2.6

+1

Je ne comprends pas votre question. Comment pouvez-vous contourner la seule chose que vous devez faire pour ne pas faire la seule chose que vous avez à faire? Fishslap! –

+0

Je veux que la classe agisse comme un nombre entier. Les implémentations pour les entiers réels sont toujours les mêmes, alors pourquoi l'implémenter chaque fois que vous l'utilisez. La méthode __add__ a du sens lorsque vous utilisez l'opérateur '+' pour tout autre chose qu'une addition réelle. –

Répondre

5

Vous devez passer outre __new__, non __init__:

class Foo(int): 
    def __new__(cls, some_argument=None, value=0): 
     i = int.__new__(cls, value) 
     i._some_argument = some_argument 
     return i 

    def print_some_argument(self): 
     print self._some_argument 

Maintenant votre travail de classe comme prévu:

>>> f = Foo(some_argument="I am a customized int", value=10) 
>>> f 
10 
>>> f + 8 
18 
>>> f * 0.25 
2.5 
>>> f.print_some_argument() 
I am a customized int 

Plus d'informations sur le remplacement new se trouve dans Unifying types and classes in Python 2.2.

7

En Python 2.4+ héritant de int fonctionne:

class MyInt(int):pass 
f=MyInt(3) 
assert f + 5 == 8 
+0

J'ai rencontré des problèmes lorsque j'utilisais des arguments nommés pour le constructeur (__init__). Quand j'appelle f = MyInt (other_argument = True), il échoue (TypeError: 'other_argument' est un argument mot-clé invalide pour cette fonction) –

+1

@ Günther Jehle: S'il vous plaît ajouter ceci à votre question. Ce commentaire ne correspond pas à votre question et n'a pas beaucoup de sens dans le contexte de cette question. Veuillez mettre à jour la question pour inclure tous les faits. –

+0

a ajouté le résultat de l'héritage de int –

2

Essayez d'utiliser une version à jour de python. Votre code fonctionne en 2.6.1.

+0

Je vais essayer cela –

+0

Ma version python est actuellement 2.5.1 –

+0

Attendez, pourquoi héritez-vous de 'object' ?? Le code fonctionne si vous héritez de 'int'. – jdb