封装- --接口,抽象, 鸭子类型 #22

知识点1.封装    1.封装.py

 1 ‘‘‘‘‘‘
 2 """
 3 封装:
 4 """
 5
 6 """
 7 1.什么是封装?
 8     就是将复杂的丑陋的,隐私的细节,隐藏到内部,对外提供简单的使用接口
 9
10     即:对外隐藏内部实现细节,并提供访问接口
11 """
12 """
13 2.为什么需要封装?
14     两个目的:
15     1.为了保证 关键数据的安全性
16     2.对外部隐藏实现细节,隔离复杂度
17 """
18 """
19 3.什么时候应该封装?
20     当有一些数据不希望外界可以直接修改时  -- 安全性
21 ?    当有一些函数不希望给外界使用时,
22      -- 复杂度
23 """
24 """
25 4.被封装的内容的特点:
26     1.外界不能直接访问
27     2.内部依然可以使用
28
29 5.权限:
30     学习封装后可以控制属性的权限
31         在Python中只有两种权限,
32         1.公开的,默认就是公开的
33         2.私有的,只有内部(当前类自己)可以使用
34 """
35
36 """
37 如何使用?
38 语法:
39 """
40 class Person:
41     def __init__(self,id_number,name,age):
42         self.__is_number = id_number
43         self.name = name
44         self.age = age
45     def show_id(self):
46         print(self.__is_number)
47 p = Person(‘2222222‘,‘llx‘,‘24‘)
48 p.__id_number = ‘1111‘
49 print(p.__id_number)  # 1111
50 # __id_number 被封装
51 p.show_id()  # 2222222

1.封装

    2.封装方法.py

 1 """"""
 2 """正常方法"""
 3
 4 class PC:
 5     def __init__(self,price,kind,color):
 6         self.price = price
 7         self.kind = kind
 8         self.color = color
 9     def open(self):
10         print(‘接通电源‘)
11         print(‘检测硬件1‘)
12         print(‘检测硬件2‘)
13         print(‘检测硬件3‘)
14         print(‘检测硬件4‘)
15         print(‘载入内核‘)
16         print(‘初始化内核‘)
17         print(‘启动GUI‘)
18         print("启动服务1")
19         print("启动服务2")
20         print("启动服务3")
21         print("启动服务4")
22         print("login....")
23         print("login....")
24         print("login....")
25
26 p = PC(20000,‘ovie‘,‘red‘)
27 print(p.__dict__)  # {‘price‘: 20000, ‘kind‘: ‘ovie‘, ‘color‘: ‘red‘}
28 p.open()
29 """
30 值:
31 接通电源
32 检测硬件1
33 检测硬件2
34 检测硬件3
35 检测硬件4
36 载入内核
37 初始化内核
38 启动GUI
39 启动服务1
40 启动服务2
41 启动服务3
42 启动服务4
43 login....
44 login....
45 login....
46 """
47
48 """封装方法"""
49 """ 语法 : __名称(双下划綫+类属性(初始化值)或方法(函数名))"""
50 class PC:
51     def __init__(self,price,kind,color):
52         self.price = price
53         self.kind = kind
54         self.color = color
55
56     def open(self):
57         print(‘接通电源‘)
58         # 封装检查硬件调用
59         self.__check()
60         print(‘载入内核‘)
61         print(‘初始化内核‘)
62         self.__run()
63         print(‘启动GUI‘)
64         self.__login()
65     def __run(self):
66         print("启动服务1")
67         print("启动服务2")
68         print("启动服务3")
69         print("启动服务4")
70     def __check(self):
71         print(‘检测硬件1‘)
72         print(‘检测硬件2‘)
73         print(‘检测硬件3‘)
74         print(‘检测硬件4‘)
75     def __login(self):
76         print("login....")
77         print("login....")
78         print("login....")
79 p = PC(40000,‘opp‘,‘蓝色‘)
80 p.open()
81 """
82 接通电源
83 检测硬件1
84 检测硬件2
85 检测硬件3
86 检测硬件4
87 载入内核
88 初始化内核
89 启动服务1
90 启动服务2
91 启动服务3
92 启动服务4
93 启动GUI
94 login....
95 login....
96 login....
97 """

2.封装方法

    3.如何访问被封装的属性.py

 1 ‘‘‘‘‘‘
 2 ‘‘‘
 3 如何在外界通过方法来访问内部的被封装属性
 4 ‘‘‘
 5 """
 6 案例:
 7     这是一个下载器类,
 8     需要提供一个缓存大小这样的属性
 9     缓存大小不能超过内存限制
10 """
11 # 定义一个下载器类
12 class Downloader:
13     # 属性
14     # filename 文件名
15     # url 域名
16     # buffer_size 缓存大小
17     def __init__(self,filename,url,buffer_size):
18         self.filename = filename
19         self.url = url
20         self.__buffer_size = buffer_size
21     # 缓存大小不能超过内存大小
22     def start_download(self):
23         # 内存大小:1024*1024
24         if self.__buffer_size <= 1024*1024:
25             print(‘开始下载....‘)
26             print(‘当前缓存器大小‘,self.__buffer_size)
27         else:
28             print(‘内存炸了‘)
29     # 设置(修改)缓存大小
30     # 一额外逻辑
31     def set_buffer_size(self,size):
32         # 缓存大小必须是整型
33         if type(size) == int:
34             print(‘缓存区大小修改成功‘)
35             self.__buffer_size = size
36         else:
37             print(‘大哥,缓存区大小必须是整型‘)
38     # 获取缓存区大小
39     def get_buffer_size(self):
40         return self.__buffer_size
41 p = Downloader(‘w3shool‘,‘http:\\www.w3school.atf‘,1024*1024)
42 #p.set_buffer_size(2048*2048)
43
44 # p.start_download()
45
46 # 访问方法 -- 原理:基于封装只有当前类可用
47 # 1.通过函数修改内部被封装的属性
48 p.set_buffer_size(2048*2048)
49 # 2.通过函数访问内部被封装的属性
50 # p.get_buffer_size()
51 print(p.get_buffer_size())
52
53 p.start_download()
54 """
55 缓存区大小修改成功
56 4194304
57 内存炸了
58 """

3.如何访问被封装的属性

    4.property装饰器.py

 1 ‘‘‘‘‘‘
 2 """
 3 property装饰器
 4 1.由来
 5     基于下文访问被封装内容方法案例,在修改关键数据是应该再加些限制
 6
 7     当然通过这个方法访问这个类,本身没什么问题,但是这个对象的使用者带来了麻烦
 8
 9     在这种情况下,使用者,必须知道哪些是    普通属性, 哪些是私有属性,需要使用不同的方法来调用 他们.
10
11     property装饰就是为了使用调用方式一致
12
13 2.3种相关方法 -- 装饰器
14     [email protected] 该装饰器用在获取属性的方法上
15     [email protected] 该装饰器用在修改属性方法上
16     [email protected] 该装饰用在删除属性方法上
17     ps:
18     key 是被property装饰属性或方法的名称
19     也就是属性的名称
20     内部会创建一个对象 变量名称就是函数名称
21     所以在使用setter和deleter时 必须保证使用对象的名称取调用方法
22     所以是 key.setter
23 """
24 # 案例
25
26 """
27 案例:
28     这是一个下载器类,
29     需要提供一个缓存大小这样的属性
30     缓存大小不能超过内存限制
31 """
32 # 定义一个下载器类
33 class Downloader:
34     # 属性
35     # filename 文件名
36     # url 域名
37     # buffer_size 缓存大小
38     def __init__(self,filename,url,buffer_size):
39         self.filename = filename
40         self.url = url
41         self.__buffer_size = buffer_size
42
43     # 获取缓存区大小
44     @property
45     def buffer_size(self):
46         return self.__buffer_size
47     # 缓存大小不能超过内存大小
48
49     @buffer_size.deleter
50     def buffer_size(self):
51         print("不允许删除该属性")
52         del self.__buffer_size
53     # 设置(修改)缓存大小
54     # 一额外逻辑
55     @buffer_size.setter
56     def buffer_size(self,size):
57         # 缓存大小必须是整型
58         if type(size) == int:
59             print(‘缓存区大小修改成功‘)
60             self.__buffer_size = size
61         else:
62             print(‘大哥,缓存区大小必须是整型‘)
63 p = Downloader(‘w3shool‘,‘http:\\www.w3school.atf‘,1024*1024)
64 #p.set_buffer_size(2048*2048)
65
66 # p.start_download()
67
68 # 访问方法 -- 原理:基于封装只有当前类可用
69 # 1.通过函数修改内部被封装的属性
70 #.buffer_size(2048*2048)
71 # 2.通过函数访问内部被封装的属性
72 # p.get_buffer_size()
73
74
75 p.start_download()
76 # 获取
77 #print(p.buffer_size)
78 # 修改
79 p.buffer_size = 1024*2096
80 # print(p.buffer_size)
81 # 删
82 del p.buffer_size
83 print(p.buffer_size)

4.property装饰器

    5.封装的实现原理.py

 1 ‘‘‘‘‘‘
 2 """
 3 1.Python实现封装的原理:替换变量名称
 4     就是在加载类的时候,把__替换成__类名__
 5     Python一般不会要求程序必须怎么做怎么做
 6
 7 2.封装:
 8     对外部隐藏内部的实现细节,并提供访问的接口
 9 3.好处:
10     1.提高安全性,
11     2.隔绝复杂度
12
13 4.语法:
14     将要封装的属性或方法名称前加上双下划綫
15
16 5.访问被隐藏的属性:
17     提供用于访问和修改的方法
18
19     使用 property装饰器可以将一个方法伪装成普通属性,保持普通属性的属性的调用方法一致
20 """
21 # 案例:
22 class A:
23     def __init__(self,key):
24         self.__key = key
25
26     # 获取方法
27     @property
28     def key(self):
29         return self.__key
30     # 修改方法
31     @key.setter
32     def key(self,re_key):
33         self.__key = re_key
34         return self.__key
35     # 删除方法
36     @key.deleter
37     def key(self):
38         del self.__key
39 p = A(‘assd‘)
40 # 获取方法
41 #print(p.key) # assd
42 # 修改方法
43 # p.key = ‘gfghfhjgg‘
44 # print(p.key)  # gfghfhjgg
45 # # 删除方法
46 # del p.key
47 print(p._A__key)  # assd
48
49 p.__name = ‘jkhg‘
50 print(p.__dict__)  # {‘_A__key‘: ‘assd‘, ‘__name‘: ‘jkhg‘}
51 print("__key".replace("__","_A__"))  # _A__key

5.封装的原理

    6.作业,计算属性.py

 1 """"""
 2 """
 3 property 可以用来实现计算属性
 4
 5     计算属性指的是:属性的值,
 6     不能直接获得,必须通过计算才能获取
 7
 8 """
 9 # 案例一
10 """正方形求面积"""
11 # 定义正方形
12 class Square:
13     # 定义正方形边
14     def __init__(self,width):
15         self.width = width
16     # 获取正方形的面积
17     @property
18     def area(self):
19         return self.width * self.width
20     @area.setter
21     def area(self,number):
22         self.width = number
23         return self.width
24     @area.deleter
25     def area(self):
26         del self.width
27
28 p = Square(5)
29 print(p.area)
30 p.width = 10
31 print(p.area)
32 # 案例二
33 # 练习: 定义一个类叫做person
34 # 包含三个属性 身高 体重   BMI
35 # BMI的值需要通过计算得来 公式   体重 / 身高的平方
36 class Person:
37     def __init__(self,high,weigh):
38         self.high = high
39         self.weigh = weigh
40     @property
41     def BMI(self):
42         return self.weigh / self.high / self.high
43 p = Person(180,87)
44 print(p.BMI)

6.计算属性,实际应用

2.接口和抽象类,鸭子类型    1.接口.py

 1 ‘‘‘‘‘‘
 2 """
 3 接口:
 4     是一组功能的集合,但是接口中仅包含功能的名字,不包含具体的实现代码
 5
 6 接口的本质:
 7     是一套协议标准,遵循这个标准的对象就能被调用
 8
 9 接口的目的:
10     就是为了提高扩张性
11
12 接口:是一套协议内容,明确子类应该具备哪些功能
13 """
14 """
15 例如电脑提前指定制定一套USB接口协议,只要你遵循该协议,你的设备就可以被电脑使用,不需要关心到底是鼠标还是键盘
16 """
17 # 案例
18 # usb接口
19 class USB:
20     def open(self):
21         pass
22     def close(self):
23         pass
24     def read(self):
25         pass
26     def write(self):
27         pass
28 # 鼠标
29 class Mouse(USB):
30     def open(self):
31         print("鼠标开机.....")
32
33     def close(self):
34         print("鼠标关机了...")
35
36     def read(self):
37         print("获取了光标位置....")
38
39     def write(self):
40         print("鼠标不支持写入....")
41 # 电脑--接口协议,传入以后按协议顺序执行
42 def pc(usb_device):
43     usb_device.open()
44     usb_device.read()
45     usb_device.write()
46     usb_device.close()
47 # 把鼠标传入电脑
48 m = Mouse()
49 # 调用鼠标
50 pc(m)
51
52 # 键盘
53 class KeyBoard(USB):
54     def open(self):
55         print("键盘开机.....")
56
57     def close(self):
58         print("键盘关机了...")
59
60     def read(self):
61         print("获取了按键字符....")
62
63     def write(self):
64         print("可以写入灯光颜色....")
65
66
67 # 来了一个键盘对象
68 k = KeyBoard()
69 pc(k)
70
71 # U盘
72 class UDisk(USB):
73     def open(self):
74         print("U盘启动了...")
75
76     def close(self):
77         print("U盘关闭了...")
78
79     def read(self):
80         print("读出数据")
81
82     def write(self):
83         print("写入数据")
84
85 u = UDisk()
86 pc(u)
87
88 """
89 在上述案例中,PC的代码一旦完成,后期无论什么样的设备 只要遵循了USB接口协议,都能够被电脑所调用
90
91 接口主要是方便了对象的使用者,降低使用者的 学习难度,只要学习一套使用方法,就可以以不变应万变
92
93 问题:
94
95 如果子类没有按照你的协议来设计,也没办法限制他,将导致代码无法运行
96
97 解决:抽象类
98 """

1.接口--定义一个接口类

    2.抽象类.py

 1 """"""
 2 """
 3 抽象类:
 4     指的是包含抽象方法(没有函数体的方法)的类
 5
 6 作用:
 7     限制子类必须类中定义抽象方法
 8 """
 9 """
10 import abc
11 abc 是 单词abstract class(抽象类:类中包含没有函数体的方法) 的缩写
12 """
13 import abc
14 class AClass(metaclass=abc.ABCMeta):
15     @abc.abstractmethod
16     def run(self):
17         pass
18     @abc.abstractmethod
19     def run1(self):
20         pass
21 # class B(AClass):
22 #
23 #     def run(self):
24 #         print("123455")
25 # b = B()
26 """
27 报错:
28 Can‘t instantiate abstract class B with abstract methods run1
29 无法用抽象方法run1实例化抽象类B
30
31 """
32 class B(AClass):
33
34     def run(self):
35         print("123455")
36     def run1(self):
37         print("4456554")
38 b = B()
39 b.run() # 123455
40 """
41 结论:
42     抽象类,位继承类做了一个限制,如果不按照格式来,会报错
43
44 最后:
45     python一般不会限制你必须怎么写,作为一个优秀的程序员,就应该自觉遵守相关协议
46
47 所以有了鸭子类型这么一说:
48 """

2.抽象类--abc模块(要求必须按照协议,否则会报错)

    3.鸭子类型--抽象类,优化.py

 1 """"""
 2 """
 3 鸭子类型:
 4     如果这个对象长得像鸭子,走路像鸭子,那就他是鸭子
 5
 6 你只要保证你的类按照相关的协议类编写,也可以达到提高扩展性的目的
 7 """
 8 # 鸭子类型
 9 # 鼠标
10 class Mouse:
11     def open(self):
12         print("鼠标开机.....")
13
14     def close(self):
15         print("鼠标关机了...")
16
17     def read(self):
18         print("获取了光标位置....")
19
20     def write(self):
21         print("鼠标不支持写入....")
22
23
24 def pc(usb_device):
25     usb_device.open()
26     usb_device.read()
27     usb_device.write()
28     usb_device.close()
29
30
31 m = Mouse()
32 # 将鼠标传给电脑
33 pc(m)
34
35
36 class KeyBoard:
37     def open(self):
38         print("键盘开机.....")
39
40     def close(self):
41         print("键盘关机了...")
42
43     def read(self):
44         print("获取了按键字符....")
45
46     def write(self):
47         print("可以写入灯光颜色....")
48
49
50 # 来了一个键盘对象
51 k = KeyBoard()
52 pc(k)
53
54
55 class UDisk:
56     def open(self):
57         print("U盘启动了...")
58
59     def close(self):
60         print("U盘关闭了...")
61
62     def read(self):
63         print("读出数据")
64
65     def write(self):
66         print("写入数据")
67
68
69 u = UDisk()
70 pc(u)

3.鸭子类型(使用已存在的类,提高扩展性)

    4.总结.py

 1 """"""
 2 """
 3 接口
 4     是一套协议规范,明确子类们应该具备哪些功能
 5
 6 抽象类
 7     是用于强制要求子类必须按照协议中规定的来实现
 8
 9 鸭子类型:
10     然而,python不推崇限制你的语法, 我们可以设计成鸭子类型,既让多个不同类对象具备相同的属性和方法
11
12 对于使用者而言,就可以以不变应万变,轻松的使用各种对象
13 """

4.总结 接口,抽象类,鸭子类型

原文地址:https://www.cnblogs.com/llx--20190411/p/11259961.html

时间: 2024-11-05 23:24:57

封装- --接口,抽象, 鸭子类型 #22的相关文章

python与鸭子类型

部分参考来源:作者:JasonDing  https://www.jianshu.com/p/650485b78d11##s1 首先介绍下面向对象(OOP)的三大特征: (1)面向对象程序设计有三大特征:封装(Encapsulation).继承(Inheritance).多态(Polymorphism).这三个单词很常见,大家还是记住为好! (2)封装(Encapsulation):类包含了数据和方法,将数据和方法放在一个类中就构成了封装. (3)继承(Inheritance):Java是单继承

023_接口类,抽象类,多态,鸭子类型,封装

1,接口类 1 class Wechat(): 2 def pay(self,money): 3 print('已经用微信支付了%s元'%money) 4 class Alipay(): 5 def pay(self,money): 6 print('已经用支付宝支付了%s元' % money) 7 wechat = Wechat() 8 ali = Alipay() 9 # wechat.pay(100) 10 # ali.pay(200) 11 #将上面两句用下面的替换, 12 def pa

封装之property,多态,鸭子类型,classmethod与staticmethod

一.封装之Property prooerty是一种特殊的属性,访问时他会执行一段功能(函数)然后返回 '''BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解) 成人的BMI数值:过轻:低于18.5正常:18.5-23.9过重:24-27肥胖:28-32非常肥胖, 高于32 体质指数(BMI)=体重(kg)÷身高^2(m) EX:70kg÷(1.75×1.75)=22.86 ''' class People: def __init__(se

面向对象之组合、封装、多态性、鸭子类型

一.组合 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之为组合 2. 为何用组合 组合也是用来解决类与类代码冗余的问题 3. 如何用组合 # class Foo: # aaa=1111 # def __init__(self,x,y): # self.x=x # self.y=y # # def func1(self): # print('Foo内的功能') # # # class Bar: # bbb=2222 # def __init__(self, m, n): # sel

16 Apr 18 封装的property 多态 鸭子类型 classmethod和staticmethod

16 Apr 18 一.      封装的property BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解) 成人的BMI数值: 过轻:低于18.5 正常:18.5-23.9 过重:24-27 肥胖:28-32 非常肥胖, 高于32 体质指数(BMI)=体重(kg)÷身高^2(m) 首先需要明确.bmi是算出来的,不是一个固定死的值,也就说我们必须编写一个功能,每次调用该功能都会立即计算一个值,但很明显人的bmi值听起来更像一个名词而非

七:Java之封装、抽象、多态和继承

本文章介绍了关于Java中的面向对象封装.抽象.继承.多态特点 Java面向对象主要有四大特性:封装.抽象.继承和多态. 一.封装 封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员. 在面向对象语言中,封装特性是由类来体现的,我们将现实生活中的一类实体定义成类,其中包括属性和行为(在Java中就是方法),就好像人类,可以具有name,sex,age等属性,同时也具有eat(),sle

企业级应用框架(二)三层架构之数据访问层的封装与抽象

接上一篇我们来对数据访问层进行封装与抽象.在上一篇我们知道,要解除BLL对DAL的依赖,我们就必须抽象出DAL层的接口,同时基于DAL的数据访问技术很多,如EF,ADO.NET,LINQ TO SQL,因此,我们的数据访问层必须对这些技术提供相应的支持.所以今天我们要做的事情有两件,第一,定义我们的数据访问层接口:第二,屏蔽各类数据库访问技术的差异,提供统一的数据库访问模型.举个例子,我们只需要修改一下我们的配置文件,就能够把ADO.NET的实现方式,改变成EF的实现方式.好下面搭建我们的三层构

关于python鸭子类型和白鹅类型

1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__reversed__,index,count对于其中的抽象方法,子类在继承时必须具体化,其余非抽象方法在继承时可以自动获得,Sequence序列必须具体化的抽象方法是__len__和__getitem__ from collections import abc class Foo(abc.Sequence): def __in

面向对象的三大特性 鸭子类型 类的约束 super的深度剖析

1.三大特性 封装 ? 把很多数据封装到?个对象中. 把固定功能的代码封装到?个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了?个很?B的函数. 那这个也可以被称为封装. 在?向对象思想中. 是把?些看似?关紧要的内容组合到?起统?进?存储和使?. 这就是封装. 继承 ? ?类可以?动拥有?类中除了私有属性外的其他所有内容. 说?了, ??可以随便?爹的东?. 但是朋友们, ?定要认清楚?个事情. 必须先有爹, 后有??. 顺序不能乱, 在py