Question

I'm teaching myself Python via an online wikibook, and came across a confusing error in one of the examples with overloading operators. According to the example:

class FakeNumber:
    n = 5
    def __add__(A,B):
        return A.n + B.n

c = FakeNumber()
d = FakeNumber()
d.n = 7

c.__imul__ = lambda B: B.n - 6
c *= d
c

is supposed to return:
1
but instead I get:
TypeError: unsupported operand type(s) for *=: 'FakeNumber' and 'FakeNumber'

I get that you can't multiply objects together, so then what is the point of c.__imul__ = lambda B: B.n - 6? Is there something missing, or where is there improper syntax?

Reference: http://en.wikibooks.org/wiki/Python_Programming/Classes#Operator_Overloading

Was it helpful?

Solution

Indeed the code is working as intended in python 2, but not in 3. A possible fix in python 3 would be the following:

class FakeNumber:
    def __init__(self, i):
        self.i = i

    def __imul__(self, B):
        self.i = self.i * B.i
        return self

a = FakeNumber(5)
b = FakeNumber(6)

a *= b

OTHER TIPS

The link explains Python 2 and you're trying it on Python 3. The difference can be explained in detail (look for "old-style classes" versus "new-style classes" if you want to know), but it resumes to: special methods like __imul__ are now always ignored if they are defined on an instance. They are only called if they are defined on the class of the instance. So the line

c.__imul__ = lambda B: B.n - 6

does not have the intended effect of defining the behavior of the += operator: c is just an instance of the class C.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top