Before we get into Python's self usage, let's go over classes and instances in Python ......
We know that the most important object-oriented concepts are class (class) and instance (instance), class is an abstract template, such as students this abstract thing, you can use a Student class to represent. Instance is created according to the class of a specific "object", each object is inherited from the class has the same method, but the respective data may be different.
1. Take the Student class for example, in Python, define the class as follows:
class Student(object): pass
(Object) indicates the class from which the class is inherited, the Object class is the class that all classes inherit.
2, instance: defined the class, you can create an instance of Student through the Student class, create an instance is realized through the class name + ():
student = Student()
3, because the class plays the role of a template, so you can create instances of the time, we believe that we must bind the attributes forced to fill in. Here we use one of Python's built-in methods.__init__
methods, such as tying the name, score, etc. attributes when the Student class is :
class Student(object): def __init__(self, name, score): = name = score
Note here that (1),__init__
The first argument to a method is alwaysself
, which indicates the class that was createdthe instance itselfTherefore, in the case of__init__
method inside, it is possible to bind various properties to self, since self points to the created instance itself. (2) With the__init__
method, you can't pass in empty parameters when creating the instance, you must pass in the same parameter as in the__init__
method matches the arguments, but self doesn't need to be passed; the Python interpreter will pass in the instance variable itself:
>>>student = Student("Hugh", 99) >>> "Hugh" >>> 99
Also, hereself
is the class itself.just like
Student
Attribute variables of the class that areStudent
class all. And thename
is an externally passed parameter, notStudent
class comes with. Therefore, the = name
means that the parameter passed from the outsidename
is assigned to the Student class' own attribute variable.。
4. Compared to ordinary numbers, there is only one difference between defining a function in classfirst parameterneverthelessInstance variables of the class itselfself
and are called without passing that parameter. Other than that, the methods (functions) of a class are no different from normal functions, and you can either use theDefault, Variable, or Keyword Parameters(*args are variable arguments, args receives a tuple,**kw is the keyword argument, kw receives a dict)。
5. SinceStudentThe class instance itself has these data, so to access these data, there is no need to access from the outside of the function to access, but can be directly in the Student class inside the definition of access to data functions (methods), so that the "data" can be encapsulated. These functions that encapsulate the data are associated with the Student class itself and are called class methods:
class Student(obiect): def __init__(self, name, score): = name = score def print_score(self): print "%s: %s" % (, )
>>>student = Student("Hugh", 99) >>>student.print_score Hugh: 99
In this way, when we look at the Student class from the outside, all we need to know is that name and score need to be given to create the instance. and how it is printed is all defined internally in the Student class.The data and logic is encapsulated in such a way that it's easy to call, but without knowing the details of the internal implementation.
To keep internal properties from being accessed externally, you can prefix the name of the property with two underscores, in Python, the variable names of instances that begin withThe beginning, it becomes a private variable (private), only internally accessible, not externally accessible, 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, nothing has changed for the external code, but it is no longer possible to access the instance variables externally.__name
and instance variables.__score
Up:
>>> student = Student('Hugh', 99) >>> student.__name Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute '__name'
This ensures that external code cannot modify the internal state of the object at will, so that the code is more robust through the protection of access restrictions.
But what if the external code wants to get the name and score? You can add methods like 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 you want to allow external code to modify the score again? You can add the set_score method to the Student class:
class Student(object): ... def set_score(self, score): self.__score = score
It is important to note that in Python, variable names are similar to__xxx__
s, that is, those that begin with a double underscore and end with a double underscore, are special variables, and special variables are directly accessible, not private variables, so they cannot be accessed using the__name__
、__score__
variable names like this.
There are times when you see instance variable names that begin with an underscore, such as _name, and such instance variables are externally accessible, but, by convention, when you see such a variable, the meaning is, "Although I can be accessed, please consider me private and don't access me at will! ".
Another benefit of encapsulation is that new methods can be added to the Student class at any time, for example:get_grade
:
class Student(object): ... def get_grade(self): if >= 90: return 'A' elif >= 60: return 'B' else: return 'C'
Likewise.get_grade
methods can be called directly on instance variables without needing to know the internal implementation details:
>>> student.get_grade() 'A'
6、self
The careful use of
(1)、self represents an instance of the class, not the class.
class Test: def ppr(self): print(self) print(self.__class__) t = Test() () Implementation results: <__main__.Test object at 0x000000000284E080> <class '__main__.Test'>
It is clear from the above example that self represents an instance of the class. And theself.__class__
then points to the class.
Note: Replacing self with this gives the same result, but it's better to use the convention self in Python.
(2)、Can self be left out?
Inside the Python interpreter, when we call (), Python actually interprets it as (t), which means that self is replaced with an instance of the class.
class Test: def ppr(): print(self) t = Test() ()
The results of the run are as follows:
Traceback (most recent call last):
File "", line 6, in <module>
()
TypeError: ppr() takes 0 positional arguments but 1 was given
The runtime alerted the error as follows: ppr was defined with no parameters, but we forced a parameter to be passed at runtime.
Since () is equivalent to (t) as explained above, the program reminds us that we passed an extra parameter t.
This is actually partially explained hereself
It may not be omitted from the definition.
Of course, it's OK if we don't pass class instances in both our definitions and invocations, which are class methods.
class Test: def ppr(): print(__class__) () running result: <class '__main__.Test'>
(3)、When inheriting, whichever instance is passed in is the one that is passed in, 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() () () p = Parent() ()
Run results:
<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>
Explanation:
There should be no comprehension problem when running(), referring to instances of the Child class.
But when running (), it is equivalent to (c), so self still refers to an instance of the Child class, and since the pprt() method is not defined in self, looking up the inheritance tree reveals that the pprt() method is defined in the parent class, Parent, and so it is called successfully.
(4)、In a descriptor class, self refers to an instance of the 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() ()
The results of the run 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: isn't the self defined in the Desc class supposed to call its instance t? How did it become an instance of the Desc class?
Since the call here is, that is, to property x of instance t of the Test class, and since there is no property x defined in instance t, the class property x is found, which is a descriptor property for instances of the Desc class only, there is no top use of any of Test's methods here.
Then we can get the same result if we call the property x directly through the class.
Here is the result of running it instead.
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'>
Summarize: the above is a small summary of the previous study of Python, now has been presented in a blog way, at the same time for the pyspark in the invocation of self encountered problems to pave the way for the back will also be compared to java, unfinished .......
To this point this article on Python self usage details of the article is introduced to this, more related Python self usage content please search for my previous articles or continue to browse the following related articles I hope you will support me in the future more!