A concept of encapsulation
In fact, packaging is everywhere in our life, such as televisions, computers, mobile phones and other items. Usually, we can only see the external shape and use the functions provided by them, but we can't see the complex hardware composition inside. These are encapsulated and can't be seen by us. We can avoid some "special" operations so that it can't work normally. Programming comes from life. There are also encapsulation operations on objects in python, so that it only provides a fixed access mode, and cannot access its internal private properties and private methods. Encapsulation in python generally refers to the encapsulation of class attributes and class methods, that is, the privatization of class attributes and class methods, as described in the following summary.
II_ And__ Privatization of properties and methods
1. Single underline_
When properties and methods in a class_ When a single underscore begins, it means that this class of protected variables and methods do not want to be accessed externally according to the coding convention. But if you want to make an interview, you won't report an error. as follows
class A(): #_ Declarations are protected properties and protected methods _name = 'Zhang San' def __init__(self): self._age = 23 def _method(self): print("My name is{},this year{}year".format(self._name, self._age)) if __name__ == '__main__': a = A() #Print dir of class A print(a.__dir__()) #Access protection variables and protection methods print(a._name) a._method()
Output results
>>> ['_age', '__module__', '_name', '__init__', '_method', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__'] Zhang San My name is Zhang San,He is 23 years old
It can be seen that_ The properties and methods starting with a single underscore are actually accessible outside the class, but according to the Convention, when we see such properties and methods, we should not access them outside.
2. Double underline__
Although the above properties and methods starting with a single underscore are protected, they can still be accessed externally. And when you see double underlined__ When using the properties and methods at the beginning, please remember that they are private properties and private methods of the class. Methods that routinely access class properties and methods outside the class and in subclasses cannot be accessed or modified, as shown below
class B(): #__ The declaration is privatized __name = 'Zhang San' def __init__(self): self.__age = 23 self.__luange = 'python' def __method(self): #Private method print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) def fun(self): #public Method print("this is a public method") if __name__ == '__main__': b = B() #Print dir of class B print(b.__dir__()) #Access private properties and private methods of class B b.fun() print(b.__name, b.__age, b.__luange) b.__method()
Output results
>>> ['_B__age', '_B__luange', '__module__', '_B__name', '__init__', '_B__method', 'fun', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__'] this is a public method Traceback (most recent call last): File "C:/Users/admin/python-learning/python Learning documents/python Basics/python Class encapsulation.py", line 56, in <module> print(b.__name, b.__age, b.__luange) AttributeError: 'B' object has no attribute '__name'
It can be seen from the results that the public method fun() of class B is normally output, but when we access the private attribute name, we throw an error: Class B has no name attribute. When the above single underline is used, we print the dir of class A. We can see that the name attribute and method method of class A are as follows in dir
Above, we also printed the private properties and private methods of class B, as follows
You can see that private properties and private methods have become_ B__ Properties and_ B__ So in our form__ It is an error to access in the form of name or name. In fact, if we use the class name ()_ Class name__ Property (instance property) or class name_ Class name__ Attribute (class attribute) will be accessed successfully. as follows
class B(): #__ The declaration is privatized __name = 'Zhang San' def __init__(self): self.__age = 23 self.__luange = 'python' def __method(self): #Private method print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) def fun(self): #public Method print("this is a public method") if __name__ == '__main__': b = B() #Print dir of class B print(b.__dir__()) #Access private properties and private methods of class B b.fun() print(B._B__name, b._B__age, b._B__luange) b._B__method()
give the result as follows
>>> ['_B__age', '_B__luange', '__module__', '_B__name', '__init__', '_B__method', 'fun', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__'] this is a public method Zhang San 23 python My name is Zhang San,He is 23 years old,I like it python.
3. Access the private properties and private methods of the parent class in the subclass
- Subclasses cannot access private properties and private methods of the parent class
class B(): #__ The declaration is privatized __name = 'Zhang San' def __init__(self): self.__age = 23 self.__luange = 'python' def __method(self): #Private method print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) def fun(self): #public Method print("this is a public method") class C(B): def __init__(self): super().__init__() def fun1(self): #Access private properties and private methods of parent class B print(self.__name, self.__age, self.__luange) self.__method() if __name__ == '__main__': c = C() c.fun1()
Output results
>>> AttributeError: 'C' object has no attribute '_C__name' AttributeError: 'C' object has no attribute '_C__method'
It can be seen that subclasses cannot access the private properties and methods of the parent class.
- When the properties and methods of a subclass have the same name as the private properties and methods of the parent class, the private properties and methods of the parent class will not be overwritten.
class B(): #__ The declaration is privatized __name = 'Zhang San' def __init__(self): self.__age = 23 self.__luange = 'python' def __method(self): #Private method print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) def fun(self): #public Method print("this is a public method") class C(B): __name = 'Li Si' def __init__(self): super().__init__() self.__age = 24 self.__luange = 'C++' def fun1(self): #Access private properties and private methods of parent class B print(self.__name, self.__age, self.__luange) self.__method() def __method(self): #The private method of class C has the same name as the parent method, but does not override the parent method print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) #Call the private method of the parent class B()._B__method() if __name__ == '__main__': c = C() #Accessing private methods of class C c._C__method()
give the result as follows
>>> My name is Li Si,He is 24 years old,I like it C++. My name is Zhang San,He is 23 years old,I like it python.
As you can see, subclass C does not override the of parent class B__ method() method. Why? Let's print the dir of B and C as follows
>>> ['_B__age', '_B__luange', '_C__age', '_C__luange', 'fun1', '_C__method', '__doc__', '_B__name', '_B__method', '_C__name', ...]
It can be seen that in dir of class C, the private attributes and private methods of parent class B are_ B__ Properties (Methods) exist. Class II C's own private properties and private methods are based on_ C__ If the property (method) exists, that is, the private property and private method of the class will_ Class name_ The form of attribute (method) exists in dir, so when the attribute and method of the subclass have the same name as the private attribute and private method of the parent class, it will not be overwritten.
Third, access and modify the private properties and methods of the class
Class can encapsulate and protect properties and methods by privatizing them. But what happens when the outside world needs access and change? Just like TV sets, computers also provide fixed interfaces.
Above, although we can pass the class name ()_ Class name__ Property (instance property) or class name_ Class name__ Property (class property) to access the private properties and private methods of a class, but this violates the programming specification and is not supported, just as it will not disassemble the TV to operate on it.
There are generally two methods to access and modify private properties and private methods of a class, as follows
1. User defined public method
class D(): __name = 'Zhang San' def __init__(self): self.__age = 23 self.__luange = 'python' def __method(self): print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) def get_value(self): return self.__name, self.__age, self.__luange def get_method(self): self.__method() def set_value(self, name, age, luange): self.__name, self.__age, self.__luange = name, age, luange if __name__ == '__main__': d = D() #Through get_ The value method accesses private properties print(d.get_value()) #Through get_ The method method accesses private methods print('=' * 30) d.get_method() #Through set_ The value method modifies private properties print('='*30) print(d.get_value()) d.set_value('Wang Er Ma Zi', 25, 'Linux') print(d.get_value()) d.get_method()
Output results
>>> ('Zhang San', 23, 'python') ============================== My name is Zhang San,He is 23 years old,I like it python. ============================== ('Zhang San', 23, 'python') ('Wang Er Ma Zi', 25, 'Linux') My name is Wang ermazi,He is 25 years old,I like it Linux.
As you can see, we use the custom get_value(),get_method() and set_ The value () method implements the access and modification of private properties and private methods.
2. property
property generally has two functions, as follows
- As a decorator, @ property turns a class's method into a read-only class property
- Property re implements the getter and setter methods of a property
Let's take a look at the following class E, as follows
class E(): __name = 'Zhang San' def __init__(self): self.__age = 23 self.__luange = 'python' def __method(self): print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) def get_value(self): return self.__name def set_value(self, name): self.__name = name getValue = property(get_value, set_value) @property def get_method(self): self.__method() if __name__ == '__main__': e = E() #visit print(e.getValue) e.get_method #modify e.getValue = 'WangTwo ' print(e.getValue)
result
>>> Zhang San My name is Zhang San,He is 23 years old,I like it python. WangTwo
As you can see, we will get_value and set_ After the value method passes in the property, the class method is converted into a class property and assigned to the getValue variable. At this time, e.getValue is read-only, that is, get_value method, e.value = 'Wang Er' is modification, i.e. get_value method. Same. Get through @ property_ Method method becomes an attribute.
The following property re implements the getter and setter methods of a property, which is different from the above writing method and more commonly used than the above.
class E(): __name = 'Zhang San' def __init__(self): self.__age = 23 self.__luange = 'python' def __method(self): print("My name is{},this year{}year,I like it{}. ".format(self.__name, self.__age, self.__luange)) @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name if __name__ == '__main__': e = E() #visit print(e.name) #modify print("Before modification:", e.name) e.name = 'Lao Wang next door' print("After modification:", e.name)
Output results
>>> Zhang San Before modification: Zhang San After modification: Lao Wang next door
Above is the first method to decorate the propert decorator with the name method, then call the decorated setter method, then we can modify the private property.