Fully understand the usage of self and pythonself in Python

Source: Internet
Author: User

Fully understand the usage of self and pythonself in Python

When I first learned how to write Python classes, I felt very troublesome. Why does it not need to be called during definition? Why cannot it be simplified 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><class '__main__.Test'>

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 <module>  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:

<class '__main__.Test'>

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> <class '__main__.Test'>

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 <class '__main__.Test'>

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, the second item in the running result of the third row is <main. test object at 0x0000000002A570B8>. 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.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.