day 28 type package

The introduction of a

Object-oriented programming has three characteristics: encapsulation, inheritance, polymorphism, the most important feature is the package. Package refers to the data and functions are integrated together, does not sound very familiar, yes, we said before "integrated" the word is actually a package of popular argument. In addition, for the package to an object or class attributes, we can strictly control access to them, realized in two steps: the hidden and open interfaces

Two hidden attribute

Python is double underlined Class mechanisms employed at the beginning of the way hidden attribute (arranged private), but in fact this is just a variant of operation, when the beginning of the class of all properties are double lines falling in the class definition phase detection automatic grammar becomes "_ __ class name attribute name" form:

class Foo:
    __N=0 # 变形为_Foo__N

    def __init__(self): # 定义函数时,会检测函数语法,所以__开头的属性也会变形
        self.__x=10 # 变形为self._Foo__x

    def __f1(self): # 变形为_Foo__f1
        print('__f1 run')

    def f2(self):  # 定义函数时,会检测函数语法,所以__开头的属性也会变形
        self.__f1() #变形为self._Foo__f1()

print(Foo.__N) # 报错AttributeError:类Foo没有属性__N

obj = Foo()
print(obbj.__x) # 报错AttributeError:对象obj没有属性__x

This deformation problems that need attention are:

1, in the properties outside the class can not directly access the beginning of the decline in the double line, but you know the class and attribute names you can spell the name: class name _ __ property, then you can visit, such as Foo._A__N, so that this There is no limit external access and operate on the ground in the strict sense, just a deformation of the grammatical meaning.

>>> Foo.__dict__
mappingproxy({..., '_Foo__N': 0, ...})

>>> obj.__dict__
{'_Foo__x': 10}

>>> Foo._Foo__N
0
>>> obj._Foo__x
10
>>> obj._Foo__N
0

2, within the class attribute is directly accessible double lines that begin to decline, such as self .__ f1 (), since a uniform deformation in the class definition at the beginning of the double type internal phase line properties decline.

>>> obj.f2()
__f1 run

3, once the definition of the class assignment after the modification occur only during the stage of the class definition, it will not be deformed.

>>> Foo.__M=100
>>> Foo.__dict__
mappingproxy({..., '__M': 100,...})
>>> Foo.__M
100

>>> obj.__y=20
>>> obj.__dict__
{'__y': 20, '_Foo__x': 10}
>>> obj.__y
20

Three open interfaces

Custom properties is to use, it is not the purpose of hiding

3.1 Hidden attribute data

The hidden data class limits direct external operation on the data, then the interface should provide class permitted indirect external operation data, the interface can be attached on the additional logic to strictly control the operation of the data

>>> class Teacher:
...     def __init__(self,name,age): #将名字和年纪都隐藏起来
...         self.__name=name
...         self.__age=age
...     def tell_info(self): #对外提供访问老师信息的接口
...         print('姓名:%s,年龄:%s' %(self.__name,self.__age))
...     def set_info(self,name,age): #对外提供设置老师信息的接口,并附加类型检查的逻辑
...         if not isinstance(name,str):
...             raise TypeError('姓名必须是字符串类型')
...         if not isinstance(age,int):
...             raise TypeError('年龄必须是整型')
...         self.__name=name
...         self.__age=age
... 
>>>
>>> t=Teacher('lili',18)
>>> t.set_info(‘LiLi','19') # 年龄不为整型,抛出异常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 11, in set_info
TypeError: 年龄必须是整型
>>> t.set_info('LiLi',19) # 名字为字符串类型,年龄为整形,可以正常设置
>>> t.tell_info() # 查看老师的信息
姓名:LiLi,年龄:19

3.2 Hidden property functions

The purpose is to isolate complexity, such as ATM withdrawals functional program, which features many other functional components, such as cards, authentication, enter the amount, small ticket printing, withdrawals, etc., but for users who only need withdrawals can develop this function interface, we can all rest functionality hidden

>>> class ATM:
...     def __card(self): #插卡
...         print('插卡')
...     def __auth(self): #身份认证
...         print('用户认证')
...     def __input(self): #输入金额
...         print('输入取款金额')
...     def __print_bill(self): #打印小票
...         print('打印账单')
...     def __take_money(self): #取钱
...         print('取款')
...     def withdraw(self): #取款功能
...         self.__card()
...         self.__auth()
...         self.__input()
...         self.__print_bill()
...         self.__take_money()
...
>>> obj=ATM()
>>> obj.withdraw()

Summarizes the hidden attribute and open interfaces, the essence is to clearly distinguish between inside and outside, inside the class can modify something in a package without affecting the code external caller; and outside the class just to get an interface, as long as the interface name, parameters unchanged, No matter how the designer to change the internal implementation code, users have no need to change the code. This provides a good basis for cooperation, as long as the interface to the same basic agreement, modify the code cause for concern.

Four property

BMI index is an indicator used to measure a person's weight and height and health effects, is calculated as

体质指数(BMI)=体重(kg)÷身高^2(m)
EX:70kg÷(1.75×1.75)=22.86

Height or weight is constantly changing, so every time you want to view the BMI values ​​need to be calculated before, but obviously BMI sounds more like a feature rather than functional, for Python decorator specializing in a property, you can in the class of "disguised" data property of the object, the object property when accessing that particular triggers execution function, and the return value as a result of this visit, e.g.

>>> class People:
...     def __init__(self,name,weight,height):
...         self.name=name
...         self.weight=weight
...         self.height=height
...     @property
...     def bmi(self):
...         return self.weight / (self.height**2)
...
>>> obj=People('lili',75,1.85)
>>> obj.bmi #触发方法bmi的执行,将obj自动传给self,执行后返回值作为本次引用的结果
21.913805697589478

Use property effectively ensure the consistency of property access. In addition property also provides a setting function and delete properties, as follows

>>> class Foo:
...     def __init__(self,val):
...         self.__NAME=val #将属性隐藏起来
...     @property
...     def name(self):
...         return self.__NAME
...     @name.setter
...     def name(self,value):
...         if not isinstance(value,str):  #在设定值之前进行类型检查
...             raise TypeError('%s must be str' %value)
...         self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME
...     @name.deleter
...     def name(self):
...         raise PermissionError('Can not delete')
...
>>> f=Foo('lili')
>>> f.name
lili
>>> f.name='LiLi' #触发name.setter装饰器对应的函数name(f,’Egon')
>>> f.name=123 #触发name.setter对应的的函数name(f,123),抛出异常TypeError
>>> del f.name #触发name.deleter对应的函数name(f),抛出异常PermissionError

Guess you like

Origin www.cnblogs.com/AaronY/p/12663887.html