Python Object-Oriented Programming (3) and python Object-Oriented Programming
Encapsulation
1. Why encapsulation?
Encapsulation is to hide the specific implementation details of data attributes and methods and only provide one interface. Encapsulation does not concern about how objects are built.
2. encapsulation includes data encapsulation and function encapsulation. Data encapsulation aims to protect privacy and function encapsulation aims to isolate complexity.
3. Data encapsulation is to add __
class People: def __init__(self,name,age,salary): self.name=name self.age=age self.__salary=salaryp=People('zhang',19,100000)print(p.name)#zhangprint(p.age)#19print(p.__salary)#AttributeError: 'People' object has no attribute '__salary'
Failed. An error is reported. Let's open the object namespace and see what happened.
print(p.__dict__)#{'name': 'zhang', 'age': 19, '_People__salary': 100000}
Oh, python has transformed _ salary into _ People _ salary.
print(p._People__salary)#100000
Therefore, Python is not absolutely hidden. As long as you know the above, it doesn't matter if you know it.
These deformation operations only occur in the class definition stage or the object definition (instantiation stage) stage.
Although the _ attribute cannot be directly accessed from the outside, it can be accessed within the class. It can be understood that in the definition phase, if the attribute starting with _ is met, the Python interpreter automatically identifies it as the _ class name_attribute, so it can be accessed within the class. In this way, we can do a little thing.
Let's first look at this
class A: def foo(self): print('from A foo') self.bar() def bar(self): print('from A bar')class B(A): def bar(self): print('from B bar')b=B()b.foo() #from A foo
# Do not think too much about the from B bar. When calling a function, do not look at the defined position.
What if I want to call the bar () function of the parent class? How to do
Class A: def foo (self): print ('from A foo') self. _ bar () def _ bar (self): print ('from A bar') class B (A): def _ bar (self ): print ('from B bar') B = B () B. foo () # from A foo # from A bar do you feel programming pleasure?
4. encapsulated applications
1) We will not allow the outside world to see how our data attributes are defined. We can only see what we allow the outside world to see through the interfaces we provide.
class People: def __init__(self,name,age,height,weight,hobby): self.__name=name self.__age=age self.__height=height self.__weight=weight self._hobby=hobby def tell_info(self): print(''' name:%s age:%s height:%s weeight:%s '''%(self.__name,self.__age, self.__height,self.__weight))p=People('zhang',18,1.90,75,'read')p.tell_info()
2) A more common scenario is that we can limit the data type and encapsulate the logic for users.
Def tell_name (self): print (self. _ name) # Change the name def set_name (self, new): if not isinstance (new, str): raise TypeError ('name must be string type') self. _ name = new
5. looking at the above operations, the user still needs p when viewing the name. tell_name () is a data attribute, but it is transformed into a function. How can we disguise it? We can use the property built-in function.
class People: def __init__(self,name,age,height,weight,hobby): self.__name=name self.__age=age self.__height=height self.__weight=weight self._hobby=hobby @property def name(self): return self.__namep=People('zhang',18,1.90,75,'read')print(p.name)#zhang
Data attributes should also be modified and deleted
@ Property def name (self): return self. _ name # If the name has been modified by property, setter and deleter @ name are available. setter def name (self, new): if not isinstance (new, str): raise TypeError ('name must be string type') self. _ name = new @ name. deleter def name (self): del self. _ namep = People ('zhang ', 18, 1.90, 75, 'read') print (p. name) # zhangp. name = 'can '# modify print (p. name) # candel p. name # Delete print (p. name) # AttributeError: 'people' object has no attribute '_ People _ name'