5

Observe the following code:

class Angle(int):
    """Basic Angle object: Angle(number)"""

    def __init__(self, angle):
        angle %= 360
        super(Angle, self).__init__(angle)

Fairly simple stuff, Angle is basically just an int that never goes above 360 or below 0. This __init__ just makes sure that the input angle matches the conditions listed prior. But for some reason the above code gives me the following output:

>>> a = Angle(322)
>>> a
322
>>> b = Angle(488)
>>> b
488

Why on earth would this be happening? The code seemed so trivial to me, but maybe I'm just missing something really obvious.

user3002473
  • 4,835
  • 8
  • 35
  • 61
  • 1
    possible duplicate of [Python: extending int and MRO for \_\_init\_\_](http://stackoverflow.com/questions/1184337/python-extending-int-and-mro-for-init) – Kirill Zaitsev Feb 22 '14 at 21:25
  • Okay, thanks, adding a custom `__new__` magic method cleared up the problem completely and maintains the rest of the code quite nicely. Thank you! – user3002473 Feb 22 '14 at 21:28

2 Answers2

3

You should be overriding __new__ for immutable classes like int

class Angle(int):
  def __new__(cls, val):
    val %= 360
    inst = super(Angle, cls).__new__(cls, val)
    return inst

see python datamodel for more info

Kirill Zaitsev
  • 4,511
  • 3
  • 21
  • 29
0

Consult new method of python's object interface.

__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

praveen
  • 3,193
  • 2
  • 26
  • 30