When you see or use self in Python, you must understand the reference of self. here we will take you to fully understand the usage of self in Python, if you need it, you may find it very troublesome to start learning the class writing method of Python. Why does it need to be defined but not called, why can't we simplify it internally to reduce the number of times we hit the keyboard? After reading this article, you will understand all the questions.
Self indicates the instance of the class, not the class.
Instance description:
class Test: def prt(self): print(self) print(self.__class__) t = Test()t.prt()
The execution result is as follows:
<__main__.Test object at 0x000000000284E080>
From the above example, we can see that self represents a class instance. Self. class points to class.
Self does not have to be written as self
Many children's shoes first learn other languages and then learn Python, so they always think that self is strange. do you want to write this?
Of course, you can rewrite the above code.
class Test: def prt(this): print(this) print(this.__class__) t = Test()t.prt()
After this is changed, the running results are the same.
Of course, we 'd better respect the conventional habits and use self.
Can self be left empty?
In the interpreter of Python, when we call t. prt (), Python is actually interpreted as Test. prt (t), that is, replacing self with a class instance.
If you are interested, you can rewrite the t. prt () line above. the actual results are the same after the operation.
In fact, it has already been partially explained that self cannot be omitted during definition. if you have to give it a try, please refer to the following:
class Test: def prt(): print(self) t = Test()t.prt()
The runtime reminder error is as follows: the prt does not have a parameter when it is defined, but a parameter is forcibly transferred during runtime.
Since t. prt () is equivalent to Test. prt (t), the program reminds us to upload another parameter t.
Traceback (most recent call last): File "h.py", line 6, in
t.prt()TypeError: prt() takes 0 positional arguments but 1 was given
Of course, it is okay if we do not upload class instances for definition and calling. this is the class method.
class Test: def prt(): print(__class__)Test.prt()
The running result is as follows:
During inheritance, it refers to the instance that is passed in, rather than the instance that defines the self class.
First look at the code
class Parent: def pprt(self): print(self) class Child(Parent): def cprt(self): print(self)c = Child()c.cprt()c.pprt()p = Parent()p.pprt()
The running result is as follows:
<__main__.Child object at 0x0000000002A47080><__main__.Child object at 0x0000000002A47080><__main__.Parent object at 0x0000000002A47240>
Explanation:
When running c. cprt (), you should not understand the problem. it refers to the instance of the Child class.
However. pprt () is equivalent to Child. pprt (c), so self is still an instance of the Child class. Because self does not define the pprt () method, it is searched up along the inheritance tree, it is found that the pprt () method is defined in the Parent class, so it will be called successfully.
In the descriptor class, self refers to the instance of the descriptor class.
Not easy to understand. first look at the instance:
class Desc: def __get__(self, ins, cls): print('self in Desc: %s ' % self ) print(self, ins, cls)class Test: x = Desc() def prt(self): print('self in Test: %s' % self)t = Test()t.prt()t.x
The running result is as follows:
self in Test: <__main__.Test object at 0x0000000002A570B8>self in Desc: <__main__.Desc object at 0x000000000283E208><__main__.Desc object at 0x000000000283E208> <__main__.Test object at 0x0000000002A570B8>
Most of my children's shoes have doubts. why should the self defined in the Desc class be the instance t that calls it? How has it become a Desc instance?
Note: You need to open your eyes and see clearly. Here t is called. x, that is, the attribute x of instance t of the Test class. because instance t does not define the attribute x, class attribute x is found, and this attribute is the descriptor attribute, it is only an instance of the Desc class, so there is no Test method used here.
If we call attribute x directly through a class, we can get the same result.
The following is the result of changing t. x to Test. x.
self in Test: <__main__.Test object at 0x00000000022570B8>self in Desc: <__main__.Desc object at 0x000000000223E208><__main__.Desc object at 0x000000000223E208> None
Topic: because many times the descriptor class still needs to know who calls the descriptor instance, the second parameter ins exists in the descriptor class to indicate the class instance that calls the descriptor, so t. x, you can see that the second item in the running result of the third row is . When Test. x is used for calling, None is returned because there is no instance.
Understanding self in python from the essence of OO
For example, if I want to operate on user data, the user data includes name and age. If the process-oriented approach is used, it is implemented as follows.
def user_init(user,name,age): user['name'] = name user['age'] = age def set_user_name(user, x): user['name'] = x def set_user_age(user, x): user['age'] = x def get_user_name(user): return user['name'] def get_user_age(user): return user['age'] myself = {} user_init(myself,'kzc',17) print get_user_age(myself) set_user_age(myself,20) print get_user_age(myself)
You can see that all user operations must be passed in with the user parameter.
If object-oriented is used, you do not need to transmit the user parameter each time, and bind the relevant data and operations in one place. in each place of this class, you can conveniently obtain data.
The reason why data can be accessed in various places of the class is that it is bound with self. The first parameter of its method can be called self or another name, self is just a convention.
The following is an object-oriented implementation. we can see that the structure is much more structured and clear and readable.
class User(object): def __init__(self,name,age): self.name = name self.age = age def SetName(self,name): self.name = name def SetAge(self,age): self.age = age def GetName(self): return self.name def GetAge(self): return self.age u = User('kzc',17) print u.GetName() print u.GetAge()
From the above example, we can see that object-oriented is actually very useful, but most people are not abstract, encapsulated, or incorrectly used.
Summary
Self needs to be defined during definition, but will be automatically passed in during the call.
The name of self is not specified, but it is best to use self as agreed
Self always refers to the instance of the class during the call.
For more information about how to use self in Python, see PHP!