3

I wrote a class in python like this

class Vector(object):
def __init__(self, coordinates):
    try:
        if not coordinates:
            raise ValueError
        self.coordinates = tuple(coordinates)
        self.dimension = len(coordinates)

    except ValueError:
        raise ValueError('The coordinates must be nonempty')

    except TypeError:
        raise TypeError('The coordinates must be an iterable')

def __add__(self,v):
    v1 = np.array(self.coordinates)
    v2 = np.array(v.coordinates)
    result = v1 + v2
    return result.tolist()

def __sub__(self, other):
    v1 = np.array(self.coordinates)
    v2 = np.array(other.coordinates)
    result = v1 - v2
    return result.tolist()

def __mul__(self, other):
    return other * np.array(self.coordinates)

def multiply(self,other):
    v = Decimal(str(other)) * np.array(self.coordinates)
    return v

def __str__(self):
    return 'Vector: {}'.format(self.coordinates)


def __eq__(self, v):
    return self.coordinates == v.coordinates

I want to overwrite the operation *, so I can achieve function like:

3*Vector([1,2,3])=Vector([3,6,9])

so I tried code like this:

    def __mul__(self, other):
    return other * np.array(self.coordinates)

however, I was disappointed to notice that this function only works when

Vector([1,2,3])*3

if I wrote:

3*Vector([1,2,3])

it says:

TypeError: unsupported operand type(s) for *: 'int' and 'Vector'

How can I get the function that works both on 3*Vector([1,2,3]) and Vector([1,2,3])*3?

thank you so much.

taras
  • 6,566
  • 10
  • 39
  • 50
chengjun zhang
  • 101
  • 1
  • 1
  • 9

2 Answers2

5

Vector([1,2,3])*3 works because Vector()*3 means "call the __mul__() function of my vector object with an int argument".

But 3*Vector([1,2,3]) doesn't work because that tries to call a multiplication function of an int object with a Vector argument: int doesn't know about your Vector class, so it throws an error.

You need to define an __rmul__() function on Vector to fix this.

Richard Inglis
  • 5,888
  • 2
  • 33
  • 37
4

This is exactly why rmul was designed.

class Vector(object):
    # ...
    def __rmul__(self, other):
       return self.__mul__(other)
Matias Cicero
  • 25,439
  • 13
  • 82
  • 154
  • although i have fulfilled this code, it seems that your code is more graceful than mine. I will take your code. thank you for your help. – chengjun zhang Jun 30 '18 at 01:38