It seems that it is popular to talk about self of python2 / 3. I also try to infuse the freshness.
class class1(object):
def method1(self):
pass
You can run this script as it is, but I recommend trying various things with repl. This script works with both python2 / 3, but the output of python2 (because it's a bit more primitive and intuitive, I've included it as well.
Beginners call it confusing, but in python the only thing you can call a "class object" is class1 here. This class1 can be confirmed by repl. type (class1) == "type".
print(class1) # <class '__main__.class1'>
print(type(class1)) # <type 'type'>
This is clearly distinguished in docs.python.
9 . Classes — Python 3 \ .8 \ .3 Documentation
In other words, what I saw in the "class definition" was, strictly speaking, the creation of a type type instance.
If you try some repls for class1 here, you can see that method1 can be called even in this state. These are of type instancemethod and are unbound. That is, it is not tied to an instance.
print(callable(class1)) # True
print(callable(class1.method1)) # True
print(class1.method1) # <unbound method class1.method1>
print(type(class1.method1)) # <type 'instancemethod'>
So, in this state, you need to specify self to specify the instance.
Create an instance.
instance1 = class1()
print(instance1) # <__main__.class1 object at 0x7f19f6368910>
instance1 is called an instance object.
9 . Classes — Python 3 \ .8 \ .3 Documentation
What happens to method1 in instance1?
print(instance1.method1) # <bound method class1.method1 of <__main__.class1 object at 0x7f19f6368910>>
print(callable(instance1.method1)) # True
print(type(instance1.method1)) # <type 'instancemethod'>
print(instance1.method1 == class1.method1) # True
It's still an instance method, but when I look at the repl, it's bound. Since it is called via the instance object, it is clear that == bound is associated with instance1.
Under this condition, python2 / 3 supplements the first argument without permission. This becomes self. That's why.
By the way, it's just a convention to name this "self", and "this" works fine.
Since python functions are just instancemethods, they can be assigned outside the class / instance.
func1 = instance1.method1
print(func1) # <bound method class1.method1 of <__main__.class1 object at 0x7f4b663e6910>>
Since it is clear that instance1 is bound in the expression on the right side, func1 can be called with no arguments.
As mentioned above
Both are of the instancemethod type internally, and the behavior on the function side has not changed. The caller is adjusting the book.
Since it is rare to call class1.method1 directly, it is necessary to add self in anticipation of execution from the instance object.
Of course, there are also static methods in other languages. You can remove the method arguments, but there is a safer way. It's a classemethod decorator.
class class2(object):
def method1(cls):
print(cls)
@classmethod
def method2(cls):
print(cls)
print(class2.method1) # <unbound method class2.method1>
print(class2.method2) # <bound method type.method2 of <class '__main__.class2'>>
At the stage of class2, method2 is already bound of class2. This is still available when called from an instance.
instance2 = class2()
print(instance2.method1) # <bound method class2.method1 of <__main__.class2 object at 0x7f33073ed950>>
print(instance2.method2) # <bound method type.method2 of <class '__main__.class2'>>
How about based on the above? Doesn't self, which I thought was troublesome, seem to be very important?
Recommended Posts