For reasoning about and maintaining, you can just think of `self` as an extra parameter to the function that gets bound to the thing to the left of the dot. In some languages, like Python, this is how it actually works, so the testing argument doesn't apply either:
>>> class C:
... def __init__(self, x):
... self.x = x
... def f(self):
... print(self.x)
...
>>> c = C(3)
>>> c.f
<bound method C.f of <__main__.C object at 0x7fdb6b9b9240>>
>>> c.f()
3
>>> C.f
<function C.f at 0x7fdb6b9b1ea0>
>>> C.f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() missing 1 required positional argument: 'self'
>>> C.f(c)
3