tags:

views:

67

answers:

4

i have a python class like so:

class TAG_Short(NBTTag):
    def __init__(self, value=None):
        self.name = None
        self.value = value

    def __repr__(self):
        return "TAG_Short: %i" % self.value

This tag is filled out at runtime, but i'd also like to be able to use it like:

mytag = TAG_Short(3)
mycalc = 3 + ( mytag % 2) / mytag

is there any method i need to add to the tag to allow me to use it as a valid numeric type?

+4  A: 

You have to overload some operators. For the example you present, these are the methods you should overload:

def __add__(self, other):
  return self.value + other

def __mod__(self, other):
  return self.value % other

def __rdiv__(self, other):
  return other / self.value

See this guide for additional info

Chubas
Do **not** forget to do this: `__radd__ = __add__`, and so on.
jcao219
Thanks man, i was hoping there was an easier way (like using __repr__ for auto string conversion) but this works too.
Thomas
+1  A: 

http://docs.python.org/reference/datamodel.html#emulating-numeric-types

__add__, __div__ and __sub__ should get you started

aaronasterling
Thanks for the awesome link.
Thomas
A: 

Yes. Overload the add method and make it behave appropriately.

Arrieta
+3  A: 

I see-- what you would like is to have something like a __as_number__ method you can define in TAG_Short, which would allow you to return a number which is then used in any place where a ValueError would be about to be raised. I have no idea if there is any way to do something like that, short of implementing that metafeature yourself.

What you can do is define __add__, __radd__, __mul__, __rmul__, etc (you must define every numeric method if you want your object to truly behave like a number in every situation), and have each of them return the result of doing the desired operation with what you consider to be the number representation of the TAG_Short object.

If you find yourself doing this often enough, you may consider implementing the metafeature you describe (or first looking for a stable implementation to reuse). It would be quite feasible in Python. I think it might even be as easy as a good-old-fashioned class to be inherited from (untested code follows), with something kind of like:

class AbstractNumberImpersonator:
    # child classes should define method .to_number()
    def __add__( self, other ):
        return self.to_number() + other
    __radd__ = __add__
    def __mul__( self, other ):
        return self.to_number() * other
    __rmul__ = __mul__
    # etc - implement all the others in the same fashion

Then you could do something like:

class TAG_Short(NBTTag,AbstractNumberImpersonator):
    def __init__(self, value=None):
        self.name = None
        self.value = value

    def __repr__(self):
        return "TAG_Short: %i" % self.value

    def to_number(self):
        return self.value
Domingo Galdos
Wow yeah, this is definately a better solution, as I have a number of tags that this needs to be applied to.
Thomas