Before introducing the self usage of Python, let's introduce the classes and instances in Python
We know that the most important concept of object-oriented is the classes (class) and the instance (instance).
A class is an abstract template, such as a student's abstract object, which can be represented by a student class.
An instance is a specific "object" that is created from a class, and each object inherits the same method from the class, but the data may be different.
1, take the student class as an example, in Python, the definition class is as follows:
class Student(object): pass
(object) Represents the class from which the class inherits, and the Object class is the class that all classes inherit.
2, Example: Define the class, you can create an instance of student through the student class, the creation of the instance is through the class name + () implementation:
student = Student()
3, because the class plays the role of the template, so you can create an instance, we think must be bound to the properties of the mandatory fill in. A built-in approach to Python is used here. __init__
For example, in the student class, bind the properties of name, score, and so on:
class Student(object): def __init__(self, name, score): self.name = name self.score = score
Note: (1) __init__
the first parameter of the method is always the one that self
represents the created class instance itself , so within the __init__
method, you can bind various properties to self, because it points to the created instance itself.
(2) with the __init__
method, when creating an instance, you cannot pass in an empty parameter, you must pass in the __init__
parameters that match the method, but self does not need to pass, the Python interpreter will pass the instance variable in itself:
In addition, this refers to the self
class itself, that is, self.name
the class Student
's property variables, is the Student
class all. name
It is the external parameter, not the Student
class that comes with it.
Therefore, self.name = name
the meaning is to assign the value of the external parameter name
to the student class's own property variables self.name
.
4, compared with the ordinary number, the definition of a function in a class is only a little different, that is, the first parameter is always the class itself instance variable self
, and when called, do not pass the parameter.
In addition, the method of the class (function) and the normal function is no different, you can use the default parameters, variable parameters or keyword parameters (*args is a variable parameter, args receives a tuple,**kw is a keyword argument, KW is receiving a dict).
5, since the Student class instance itself has this data, then to access the data, there is no need to access from outside the function, but can directly within the Student class to define the access to the data function (method), so that the "data" can be encapsulated.
These functions of encapsulating data are associated with the student class itself, which is called the class method:
class Student(obiect): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print "%s: %s" % (self.name, self.score)
In this way, we look at the student class from the outside, just need to know that the creation of the instance needs to give name and score.
And how to print, is defined inside the student class, the data and logic are encapsulated, the invocation is easy, but do not know the details of the internal implementation.
If you want internal properties to be inaccessible externally, you can add two underscores to the name of the property.
in Python, if the variable name of an instance starts with a private variable (private), it can only be accessed internally and cannot be accessed externally, so let's change the Student class:
class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def print_score(self): print "%s: %s" %(self.__name,self.__score)
After the change, there is no change to the external code, but the instance variables and instance variables cannot be accessed externally .__name
.__score
:
Student(‘Hugh‘, 99)>>> student.__nameTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: ‘Student‘ object has no attribute ‘__name‘
This ensures that external code cannot arbitrarily modify the state inside the object, so that the code is more robust through access-restricted protection.
But what if external code gets name and score? You can add methods such as Get_name and Get_score to the student class:
class Student(object): def get_name(self): return self.__name def get_score(self): return self.__score
What if I want to allow external code to modify score? You can add Set_score methods to the Student class:
class Student(object): def set_score(self, score): self.__score = score
It is important to note that in Python, the variable name is similar, which starts with a double underscore, and ends with a double underscore, which is a special variable that __xxx__
can be accessed directly, not a private variable, so __name__
__score__
the variable name cannot be used.
There are times when you see an instance variable name that starts with an underscore, such as _name, which can be accessed outside of an instance variable, but, as you see in the conventional rules, when you look at a variable like this, it means, "although I can be accessed, please treat me as a private variable and don't feel free to access it."
Another benefit of encapsulation is the ability to add new methods to the student class at any time , such as: get_grade
class Student(object): ... def get_grade(self): if self.score >= 90: return ‘A‘ elif self.score >= 60: return ‘B‘ else: return ‘C‘
Similarly, the get_grade
method can be called directly on an instance variable without needing to know the internal implementation details:
>>> student.get_grade()‘A‘
6, self
the careful use
(1), selfrepresents an instance of a class, not a class.
class Test: def ppr(self): print(self) print(self.__class__)t = Test()t.ppr()执行结果:<__main__.Test object at 0x000000000284E080><class ‘__main__.Test‘>
As can be seen from the above example, self represents an instance of a class. Instead, self.__class__
point to the class.
Note: Change self to this and the result is the same, but Python is best used by the conventional self.
(2), selfcan not write?
Inside the Python interpreter, when we call T.PPR (), Python is actually interpreted as TEST.PPR (t), which is to replace self with an instance of the class.
class Test: def ppr(): print(self)t = Test()t.ppr()
The results of the operation are as follows:
Traceback (most recent call last): File "cl.py", line 6, in <module> t.ppr()TypeError: ppr() takes 0 positional arguments but 1 was given
The runtime reminder error is as follows: PPR does not have parameters when it is defined, but we are forced to pass a parameter when we run it.
Since the above explained that T.PPR () is equivalent to TEST.PPR (t), the program reminds us to pass a parameter T more.
In fact, it has been partially explained that self
the definition cannot be omitted.
Of course, this is the class method if neither of our definitions nor the invocation is capable of passing class instances.
class Test: def ppr(): print(__class__)Test.ppr()运行结果:<class ‘__main__.Test‘>
(3), at the time of inheritance, which instance is passed in, which is the incoming instance, not the instance of the class that defines self.
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()
Operation Result:
object at 0x0000000002A47080><__main__.Child object at 0x0000000002A47080><__main__.Parent object at 0x0000000002A47240>
Explain:
The problem should not be understood when running c.cprt (), referring to an instance of the child class.
However, when running C.pprt (), it is equivalent to CHILD.PPRT (c), so self refers to an instance of the child class, and because the Pprt () method is not defined in self, the Pprt () method is defined in the parent class, as it is found on the inheritance tree. So it will be successfully called.
(4), in a descriptor class, self refers to an instance of a descriptor class
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 results of the operation are 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‘>
The main question here should be: Does the self defined in the Desc class be the instance t that calls it? How does it become an instance of the Desc class?
Because T.x is called here, that is, the property x of the instance T of the test class, because the attribute x is not defined in the instance T, the class attribute x is found, and the property is a descriptor attribute, which is an instance of the Desc class, so there is no method for the test.
Then we can get the same result if we call property X directly through the class.
Here is the result of changing the t.x to Test.x run.
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‘>
Self usage in Python