---
id: 66682150151af29efec9727d
title: Step 33
challengeType: 20
dashedName: step-33
---

# --description--

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.

# --hints--

You should define a method named `__getattribute__` with two parameters, `self` and `attr`, inside the `R2Vector` class.

```js
({ test: () => assert(runPython(`_Node(_code).find_class("R2Vector").find_function("__getattribute__").has_args("self, attr")`)) })
```

Your `__getattribute__` method should return the string `'calling __getattribute__'`.

```js
({ test: () => assert(runPython(`_Node(_code).find_class("R2Vector").find_function("__getattribute__").has_return("'calling __getattribute__'")`)) })
```

# --seed--

## --seed-contents--

```py
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)}')

```
