Python urllib2 library module Python class operator overloading Part 2
Feb 10

I have been converting a C++ plugin to Python and I came across some C++ code that I was unsure how to convert to Python. I needed to overload several operators like +, -, <<, and [] so how does one go about this? First thing which is always best is to find the python.org help docs.

http://www.python.org/doc/2.5.2/ref/numeric-types.html

Unfortunately they dont have any good examples so I went searching for more. And here is an example I compiled after my search concluded. The lambda function might seem a bit confusing at first but it simply defines two variables ( in this case ) then it runs an expression and at the end of it, it defines what those variables are. The map() function is even more simple. map() can run a function on a list. For example:

#map() example
def add_one(a):
	return (a+1)

foo = [1,2,3,4]
foobar = map(add_one, foo)
print foobar
>>[2, 3, 4, 5]

lambda is special in that it is a function and operates on lists so its allowed to be inside of map()

#lambda example
foo = [1,2,3,4]
bar = [1,2,3,4]
foobar = lambda x, y: x + y, foo, bar
print foobar
( at 0x0000000017A9BEB8>, [1, 2, 3, 4], [1, 2, 3, 4])

And last here is the overload operators example:

# map() takes two (or more) arguments, a function and a list to apply the function to
# lambda can be put anywhere a function is expected
# map() calls lambada for every element in the self list
# since Vector has overloaded __getitem__ and __len__ definitions
# the Vector object can be considered a list
# the lambda function adds each other item to each item in the list
# note this only adds objects that can typicaly be added by python

# print statements added to show what is getting called
class Vector:

	def __init__(self, data):
		print "__init__"
		self.data = data

	def __call__(self, varA, varB):
		print "__call__"
		print "do something with ", varA, " and ", varB

	# overload print
	# repr returns a string containing a printable representation of an object
	# otherwise printing a Vector object would look like:
	#<__main__.Vector instance at 0x0000000017A9DF48>
	def __repr__(self):
		print "__repr__"
		return repr(self.data)

	# overload +
	def __add__(self, other):
		print "__add__"
		return Vector(map(lambda x, y: x+y, self, other))

	# overload -
	def __sub__(self, other):
		print "__sub__"
		return Vector(map(lambda x, y: x-y, self, other))

	# overload /
	def __div__(self, other):
		print "__div__"
		return Vector(map(lambda x, y: x/y, self, other))

	# overload *
	def __mul__(self, other):
		print "__mul__"
		return Vector(map(lambda x, y: x*y, self, other))

	# overload %
	def __mod__(self, other):
		print "__mod__"
		return Vector(map(lambda x, y: x%y, self, other))

	# overload []
	def __getitem__(self, index):
		print "__getitem__"
		return self.data[index]

	# overload set []
	def __setitem__(self, key, item):
		print "__setitem__"
		self.data[key] = item

	# return size to len()
	def __len__(self):
		print "__len__"
		return len(self.data)

# Execute this in the Python script tab

vecA = Vector([1, 2, 3])
>>__init__


vecA( 1, 2 )
>>__call__
>>do something with  1  and  2


print vecA
>>__repr__
>>[1, 2, 3]


vecB = vecA + vecA
>>__add__
>>__len__
>>__len__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__init__


vecB = vecA - vecA
>>__sub__
>>__len__
>>__len__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__init__


vecB = vecA / vecA
>>__div__
>>__len__
>>__len__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__init__


vecB = vecA * vecA
>>__mul__
>>__len__
>>__len__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__init__


vecB = vecA % vecA
>>__mod__
>>__len__
>>__len__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__getitem__
>>__init__


print vecB[2]
>>__getitem__
>>0


vecB[2] = 10
>>__setitem__


len(vecB)
>>__len__
>># Result: 3 #

Happy programming!
-RyanT

Leave a Reply