Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integer object whose value can be changed after definition?

Tags:

python

I need a class that is an integer whose value can be changed after the object is created. I need this class to define a size that is first specified in millimeters. Later when the user-interface is created, I get a factor from the device-context that converts millimeters to pixels. This factor should change the millimeter-value of my object to a pixel-value.

I tried to subclass int (see increment int object), but int is immutable so I can't change its value.

class UiSize(int):
    def __new__(cls, value=0):
        i = int.__new__(cls, value)
        i._orig_value = value
        return i

    def set_px_per_mm(self, px_per_mm):
        pixel_value = int(round(self._orig_value * px_per_mm))
        print "pixel_value", pixel_value
        # how to set the new pixel_value to the object's value ?

s = UiSize(500)
s.set_px_per_mm(300.0 / 500.0)
print "1px + 500mm =", 1 + s, "px" # the result should be 301 pixels

The answer in increment int object was to build my own class with all the int's methods. So I tried this:

class UiSize2(object):
    def __init__(self, value=0):
        self._int_value = int(value)

    def __add__(self, other):
        return self._int_value.__add__(other)

    def set_px_per_mm(self, px_per_mm):
        self._int_value = int(round(self._int_value * px_per_mm))

s = UiSize2(500)
s.set_px_per_mm(300.0 / 500.0)
print "500mm + 1 =", s + 1, "px"

I works for 's + 1', but for '1 + s' I get a TypeError:

>>> print "1 + 500mm =", 1 + s, "px"
TypeError: unsupported operand type(s) for +: 'int' and 'UiSize2'
like image 812
ErwinP Avatar asked Oct 06 '12 20:10

ErwinP


1 Answers

You need to define the __radd__ magic method ("right add") to control behavior when your custom type is on the right hand side of an addition. You'll need to do the same for __rmul__, __rsub__, etc. to give right-hand versions of all operations.

like image 171
BrenBarn Avatar answered Oct 13 '22 15:10

BrenBarn