Inner class function without self
Let me explain with an example:
class TestClass(object):
def __init__(self):
self.arg = "arg"
def test1():
print("class method test1, Hey test")
@classmethod
def test2(cls):
print("class method test2, Hey test")
def test3(self):
print("instance method test3, Hey test")
Look what happens when you call test1 with the class or with the instance:
First:
TestClass.test1() #called from class
class method test1, Hey test
TestClass().test1() #created an instance TestClass()
Traceback (most recent call last):
File "python", line 1, in <module>
TypeError: test1() takes 0 positional arguments but 1 was given
that's because when you create an instance, the self
parameter is used, but here, the method has not the self parameter, that's why it brakes.
next one!
TestClass.test2()
class method test2, Hey test
TestClass().test2()
class method test2, Hey test
That worked for instance and for class, why? well, as you can see test2(cls) take an argument, cls
, here, I'm not using it, so, it's ok that it works.
bring me the next subject, muajaja
TestClass().test3()
instance method test3, Hey test
TestClass.test3()
Traceback (most recent call last):
File "python", line 1, in <module>
TypeError: test3() missing 1 required positional argument: 'self'
That's easy to see, when you call it as class, you haven't provided the self parameter
In python 3, there is no difference between a function and a function defined in a class:
def test():
print("Hey test")
class TestClass:
def test():
print("Hey test")
test() # works
TestClass.test() # also works
Both of these are normal functions.
The magic of the implicit self
argument happens when you access a function through an instance of the class, like this:
obj = TestClass()
obj.test() # throws an error because the test function doesn't accept arguments
This is when the function test
is turned into the (bound) method test
. You can see the difference if you print them:
print(TestClass.test)
print(instance.test)
# output:
# <function TestClass.test at 0xaaaaaa>
# <bound method TestClass.test of <__main__.TestClass object at 0xbbbbbb>>
To sum it up:
- Accessing a function through the class gives you the original function.
- Accessing a function through an instance gives you a method with a bound
self
argument.
For details about how exactly this conversion from function to bound method works, see the descriptor how-to, and specifically the section about functions.