封装

1\ 封装

在Python中没有真正的隐藏,只有语法级别的限制,可以通过类名还可以查看数据

 1 #封装数据
 2 #封装功能
 3 class Teacher:
 4     __school='oldboy' #_Teacher__school
 5     def __init__(self,name,salary):
 6         self.name=name
 7         self.__salary=salary #self._Teacher__salary
 8 
 9     def __foo(self):
10         print('====>')
11 t=Teacher('egon',3000)
12 
13 #print(t.__school)
14 # print(Teacher.__dict__)
15 
16 #t.foo()  #封装后,无法查看,但可以通过类 的属性来查看
17 # t._Teacher__foo()   #  ====>
18 #
19 #
20 #print(t.salary)
21 #print(t.__salary)
22 print(t.__dict__)#{'name': 'egon', '_Teacher__salary': 3000}
23 #
24 print(t._Teacher__salary)#3000
25 
26 #这种变形操作只在定义阶段发生
27 Teacher.__N=111111
28 print(Teacher.__dict__)
29 
30 #
31 t.__x=1
32 print(t.__dict__)
 1 #在类的外部,无法直接使用变形的属性,但是在类的内部可以直接使用
 2 class Teacher:
 3     __school='oldboy' #_Teacher__school='oldboy'
 4     def __init__(self,name,salary):
 5         self.name=name
 6         self.__salary=salary #self._Teacher__salary=salary
 7 
 8     def foo(self):
 9         print('====>',self.__salary)
10         # print('====>',self._Teacher__salary)
11 t=Teacher('egon',3000)
12 
13 # print(t.__salary)
14 t.foo()  #====> 3000

2\对象通过父类调用封装的函数属性,

 1 class Foo:
 2     def __func(self): #_Foo__func
 3         print('from Foo')
 4 
 5 class Bar(Foo):
 6     def __func(self): #_Bar__func
 7         print('from Bar')
 8 
 9 
10 
11 b=Bar()
12 #b.func()  #被封装,找不到, 报错  AttributeError: 'Bar' object has no attribute 'func'
13 b._Foo__func()#from A.foo  对象通过父类调用父类的函数
14 b._Bar__func()#from A.bar  对象通过类名调用类的函数
 1 class A:
 2     def foo(self):
 3         print('from A.foo')
 4         self.__bar() #self._A__bar()
 5 
 6 
 7     def __bar(self): #_A__bar()
 8         print('from A.bar')
 9 
10 class B(A):
11     def __bar(self): #_B__bar
12         print('from B.bar')
13     pass
14 
15 b=B()
16 b.foo()#from A.foo   from A.bar
17 # 要调用foo()属性,b本身的对象没有foo(),就从B类里面找,B类里面也没有,从A类里找,有,打印'from A.foo',同时又找到了self.__bar()
18 #函数,执行print('from B.bar')

3\用户的数据封装后,用户查看信息,同时可以修改,在修改前加上逻辑判断

 1 class People:
 2     def __init__(self,name,age,sex,height,weight):
 3         self.__name=name
 4         self.__age=age
 5         self.__sex=sex
 6         self.__height=height
 7         self.__weight=weight
 8 
 9     def tell_name(self):
10         print(self.__name)
11 
12     def set_name(self,val):  #set_name就是提高了一个接口,用于用户修改个人信息
13         if not isinstance(val,str):  #加上了逻辑判断,用户输入的必须是字符串,不是,就触发报错
14             raise TypeError('名字必须是字符串类型')
15         self.__name=val   #如果输入的是字符串,就添加
16 
17     def tell_info(self):
18         print('''
19         ---------%s info
20         name:%s
21         age:%s
22         sex:%s
23         height:%s
24         weight:%s
25         ''' %(self.__name,
26               self.__name,
27               self.__age,
28               self.__sex,
29               self.__height,
30               self.__weight))
31 
32 egon=People('egon',18,'male','179cm','70kg')
33 #egon.tell_info()
34 
35 # ---------egon
36 # info
37 # name:egon
38 # age: 18
39 # sex: male
40 # height: 179
41 # cm
42 # weight: 70
43 # kg
44 
45 
46 
47 #
48 egon.set_name('林大昆')
49 # egon.set_name(123123123)  #  raise TypeError('名字必须是字符串类型'),,TypeError: 名字必须是字符串类型
50 
51 egon.tell_info()
52 
53 #修改后的用户信息
54 # ---------林大昆
55 # info
56 # name:林大昆
57 # age: 18
58 # sex: male
59 # height: 179
60 # cm
61 # weight: 70
62 # kg

 

4\ property的装饰器使用

 1 class People:
 2     def __init__(self,name,age,sex,height,weight):
 3         self.__name=name
 4         self.__age=age
 5         self.__sex=sex
 6         self.__height=height
 7         self.__weight=weight
 8     #
 9     # def tell_bmi(self):
10     #     res = self.__weight / (self.__height ** 2)
11     #     print('name:%s bmi:%s' % (self.__name, res))
12 
13     @property   #  property是把函数的属性装饰成数据属性,直接用,不加括号
14     def bmi(self):
15         res=self.__weight / (self.__height ** 2)
16         return res
17         print('name:%s bmi:%s'  %(self.__name,res))
18     #bmi=property(bmi)
19 
20     def tell_name(self):
21         print(self.__name)
22 
23     def set_name(self,val):
24         if not isinstance(val,str):
25             raise TypeError('名字必须是字符串类型')
26         self.__name=val
27 
28     def tell_info(self):
29         print('''
30         ---------%s info
31         name:%s
32         age:%s
33         sex:%s
34         height:%s
35         weight:%s
36         ''' %(self.__name,
37               self.__name,
38               self.__age,
39               self.__sex,
40               self.__height,
41               self.__weight))
42 
43 egon=People('egon',18,'male',1.79,70)
44 # egon.tell_info()
45 #
46 # egon.tell_name()
47 
48 # egon.tell_info()
49 
50 # egon.set_name('林大昆')
51 # egon.set_name(123123123)
52 # egon.tell_info()
53 
54 #egon.tell_bmi()    #通过tell_bmi函数接口直接调用了结果
55 print(egon.bmi)   #21.847008520333322

将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

在Python中,数据都是私有的,提供接口取获取和设置,通过property的方法实现

class People:
    def __init__(self,name,age,sex,height,weight,permission=False):
        self.__name=name
        self.__age=age
        self.__sex=sex
        self.__height=height
        self.__weight=weight
        self.permission=permission

    @property
    def name(self):
        return self.__name

    @name.setter   #修改姓名,,做逻辑判断
    def name(self,val):
        if not isinstance(val,str):
            raise  TypeError('must be str')
        self.__name=val

    @name.deleter  #删姓名,做
    def name(self):
        if not self.permission:
            raise PermissionError('不让删')
        del self.__name

egon=People('egon',18,'male',1.79,70)


# print(egon.name)

#egon.name=123  #修改姓名,必须为字符串才行
# print(egon.name)
# print(egon.permission)
egon.permission=True
del egon.name  #删除姓名
egon.name='alex'  #给姓名再赋值
print(egon.name)

 

posted @ 2017-07-06 16:38  谷子的  阅读(203)  评论(0编辑  收藏  举报