## Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

### Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

# Python "magic methods" clarification

I'm having trouble wrapping my head around what these methods ( x ) do exactly. I've found a few links that explain them somewhat, but I really haven't been able to pinpoint exactly what they are intended for. Can someone help me clarify exactly what they do? Are they specifically for objects/inheritance? Thanks in advance! I can post the links to the articles I've found if anyone is interested.

The magic methods cover a lot of ground but one large aspect of them is operator overloading. I threw together an example `Vector` class to showcase some of them:

```class Vector(object):
def __init__(self, components=[]):
self.components = components

# Defines the behaviour for addition.
# Since we're making a Vector class we'll add corresponding components together
if len(self) == len(other):
result = []
for left, right in zip(self, other):
result.append(left + right)
return result
else:
raise ArithmeticError()

def __sub__(self, other):
# Similar setup to addition, just subtracting each component.
if len(self) == len(other):
result = []
for left, right in zip(self, other):
result.append(left - right)
return result
else:
raise ArithmeticError()

def __mul__(self, other):
# We'll do something more suited to a vector and return the dot product
if len(self) == len(other):
result = 0
for left, right in zip(self, other):
result += left * right
return result
else:
raise ArithmeticError()

def __eq__(self, other):
# We'll treat the vectors as equal if their components are equivalent and in the same order
# This is the default behaviour for a list so we can use the __eq__ method of it here.
return self.components == other.components

def __ne__(self, other):
# Reuse the code from the equality overload then flip the result
return not self == other

def __getitem__(self, item):
# Called when using this class like a list
return self.components[item]

def __contains__(self, item):
# This is called with keywords such as "in"
return item in self.components

def __len__(self):
# This is called when the len built in function is passed a Vector
return len(self.components)

def __iter__(self):
# Use the list's iterator so we don't have to write our own
# Used for things like for loops
return iter(self.components)

def __str__(self):
# String representation of the vector
return "{}".format(self.components)

if __name__ == "__main__":
vec1 = Vector([1,2,3])
vec2 = Vector([9,8,7])