curriculum/challenges/english/blocks/learn-special-methods-by-building-a-vector-space/66682150151af29efec9727d.md
The __getattribute__ method is called under the hood any time you try to access an instance attribute. If the attribute is not found at the instance level, the method will search for it at the class level, and eventually in parent classes.
Inside your class, define a __getattribute__ method with two parameters, self and attr, and make it return the string 'calling __getattribute__'. You'll override momentarily the default implementation just to see how the attribute access works.
You should define a method named __getattribute__ with two parameters, self and attr, inside the R2Vector class.
({ test: () => assert(runPython(`_Node(_code).find_class("R2Vector").find_function("__getattribute__").has_args("self, attr")`)) })
Your __getattribute__ method should return the string 'calling __getattribute__'.
({ test: () => assert(runPython(`_Node(_code).find_class("R2Vector").find_function("__getattribute__").has_return("'calling __getattribute__'")`)) })
class R2Vector:
def __init__(self, *, x, y):
self.x = x
self.y = y
def norm(self):
return sum(val**2 for val in vars(self).values())**0.5
def __str__(self):
return str(tuple(getattr(self, i) for i in vars(self)))
def __repr__(self):
arg_list = [f'{key}={val}' for key, val in vars(self).items()]
args = ', '.join(arg_list)
return f'{self.__class__.__name__}({args})'
--fcc-editable-region--
--fcc-editable-region--
class R3Vector(R2Vector):
def __init__(self, *, x, y, z):
super().__init__(x=x, y=y)
self.z = z
v1 = R2Vector(x=2, y=3)
v2 = R3Vector(x=2, y=2, z=3)
# print(f'v1 = {v1}', f'\nrepr = {repr(v1)}')
# print(f'v2 = {v2}', f'\nrepr = {repr(v2)}')