2009-08-27 14 views
2

J'essaie de dériver une classe à partir d'une primitive python, le flottant, dans le but d'imprimer une chaîne de caractères différente quand elle est imprimée.accéder au type primitif de classe de base en python

Comment puis-je accéder aux données sous-jacentes de la classe dérivée lorsque je fais cela?

Voici un exemple simplifié de ce que je suis en train de faire:

class efloat(float): 
    def __repr__(self): 
     return "here's my number: %s" % str(WHAT CAN I PUT HERE???) 

Ok, Merci les gens! Je pense que je comprends maintenant. Voici la classe finie pour tous ceux qui est curieux:

import math 

class efloat(float): 
    """efloat(x) -> floating point number with engineering representation when printed 
     Convert a string or a number to a floating point number, if possible. 
     When asked to render itself for printing (via str() or print) it is normalized 
     to engineering style notation at powers of 10 in multiples of 3 
     (for micro, milli, kilo, mega, giga, etc.)   
    """ 

    def _exponent(self): 
     if self == 0.0: 
      ret = 0 
     else: 
      ret = math.floor(math.log10(abs(self))) 
     return ret 

    def _mantissa(self): 
     return self/math.pow(10, self._exponent()) 

    def _asEng(self): 
     shift = self._exponent() % 3 

     retval = "%3.12ge%+d" % (self._mantissa()*math.pow(10, shift), self._exponent() - shift) 
     return retval 

    def __str__(self): 
     return self._asEng() 

    def __repr__(self): 
     return str(self) 

    def __add__(self, x): 
     return efloat(float.__add__(self, float(x))) 

    def __radd__(self, x): 
     return efloat(float.__add__(self, float(x))) 

    def __mul__(self, x): 
     return efloat(float.__mul__(self, float(x))) 

    def __rmul__(self, x): 
     return efloat(float.__mul__(self, float(x))) 

    def __sub__(self, x): 
     return efloat(float.__sub__(self, float(x))) 

    def __rsub__(self, x): 
     return efloat(float.__rsub__(self, float(x))) 

    def __div__(self, x): 
     return efloat(float.__div__(self, float(x))) 

    def __rdiv__(self, x): 
     return efloat(float.__rdiv__(self, float(x))) 

    def __truediv__(self, x): 
     return efloat(float.__truediv__(self, float(x))) 

    def __rtruediv__(self, x): 
     return efloat(float.__rtruediv__(self, float(x))) 

    def __pow__(self, x): 
     return efloat(float.__pow__(self, float(x))) 

    def __rpow__(self, x): 
     return efloat(float.__rpow__(self, float(x))) 

    def __divmod__(self, x): 
     return efloat(float.__divmod__(self, float(x))) 

    def __neg__(self): 
     return efloat(float.__neg__(self)) 

    def __floordiv__(self, x): 
     return efloat(float.__floordiv__(self, float(x))) 
+0

Il n'y a pas de style Java (ou le style C++) « primitive » les types. float est une classe intégrée. S'il vous plaît appelez les types "intégrés", pas les types "primitifs". –

+0

Ok, bon point. –

Répondre

4

Si vous ne substituez __str__, qui va encore accéder à la méthode sous-jacente, donc:

class efloat(float): 
    def __repr__(self): 
     return "here's my number: %s" % self 

fonctionnera. Plus généralement, vous pouvez utiliser self+0, self*1 ou toute autre manipulation d'identité que vous n'avez pas explicitement annulée; si vous les annulez tous, dans le pire des cas, float.__add__(self, 0) ou similaire.

+0

Merci, ça le fait fonctionner. Donc, "self" fait référence au nombre à virgule flottante IEEE754 sous-jacent parce que je n'ai rien fait pour muck avec ça? –

+0

'self' fait référence à" cet objet ": toute méthode que vous n'avez pas redéfinie va directement dans la classe parent. J'ai aussi montré comment demander explicitement l'implémentation de la classe parente au cas où vous auriez tout écrasé! -) –

+1

'% s' appelle implicitement' str'. Donc vous faites '% str (self)', qui sera le float standard .__ str__. Vous pouvez revenir à un flottant normal en appelant 'float', par exemple:' e = efloat (9.3); f = flotteur (e); type d'impression (f) ' –

2

Vous pouvez appeler les méthodes de la classe de base, en y accédant de la classe de base pour obtenir une méthode non liée et les appeler à l'auto:

class myfloat(float): 
    def __str__(self): 
     return "My float is " + float.__str__(self) 

print(myfloat(4.5)) 
+0

Merci. Je l'ai fonctionné maintenant! –

Questions connexes