[转载] python基础:面向对象-封装
参考链接: Python中的面向对象编程2(数据隐藏和对象打印)
文章目录
1、封装的含义2、封装示例1、python中封装功能的实现
3、封装的好处1、封装数据2、降低复杂度
4、封装的特性1、@property方法
1、封装的含义
例子:手机拨打电话,背后的实现是一个很复杂的流程: 1、手机内部功能实现 2、信号与基站进行交互 3、手机对收到的信号进行解码 4、调用手机听筒,将收到的信号实时解码并转化为音频,实现通话。 但是在实际使用中,使用者只需要输入号码拨打电话就可完成通话。
这就是面对对象封装的概念。所以封装的一大特点:就是将复杂的信息、流程给包起来,内部处理,让使用者只需要通过简单的操作步骤,就能实现。 参考:(https://segmentfault.com/a/1190000018963865?utm_source=tag-newest)
2、封装示例
1、python中封装功能的实现
'''
1.封装:类就是个麻袋,
2.定义私有的,只在类内部使用,外部无法访问(_,__)
3.明确区分内外,内部的实现逻辑,外部无法知晓,并且为封装到内部的逻辑提供一个访问接口给
外部使用。
'''
class People:
# __ :双下划线,这就是在类中封装的语法
__region = "武汉" # _ People__region 实际发生了变形
def __init__(self, name, age):
self.__name = name
self.age = age
def print_info(self):
print('姓名:%s,年龄:%s,地区:%s'%(self.__name,self.age,self.__region))
obj = People('金鞍少年', 18) # 实例化对象并传入参数
print(obj.age) # 结果-- 18
obj.print_info() # 结果-- 姓名:金鞍少年,年龄:18,地区:武汉
print(obj.__region) # 报错:AttributeError: 'People' object has no attribute '__region',证明__region被私有化封装了
print(People.__dict__) # 查看类的属性和方法
# {'__module__': '__main__', '_People__region': '武汉', '__init__': <function People.__init__ at 0x000001541032C160>, 'print_info': <function People.print_info at 0x000001541032C310>, '_People__FindName': <function People.__FindName at 0x000001541032C3A0>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
# 通过分析知道,在类中__region,是以_People__region存储的
print(obj._People__region) # 结果 :武汉
这种自动变形的特点,就是封装:
在属性前面加两个下划线,表示对该属性进行隐藏,设置成私有,在内部都会变成成:_类名.__属性名类中定义的__region只能在内部使用,如self._region,引用的就是变形的结果 self. People__region这种变形其实正是针对内部的变形,也就是在类内部定义阶段就发生了变形(参考下面代码)。
class Foo:
__N = 1 # 数据(属性)的封装
def __info(self): # 方法封装
print(self.__N)
def print_info(self):
self.__info() # 内部调用封装方法
obj = Foo()
obj.print_info() # 结果 1
obj._Foo__info() # 通过调用变形后的方法名进行调用
Foo.__M = 10 # 类定义之后,外部调用,语法不会发生变形。
print(Foo.__M) # 结果 10
封装在某种意义上就是简单的隐藏: 1,这种语法变形机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__方法,然后就可以访问了,如 obj._Foo__info() 2.变形的过程只在类的定义是发生一次,在定义后的赋值操作,不会变形 ,如:Foo.__M = 10
3、封装的好处
虽说封装只是一个语法变形机制的实现,但是其好处有好几点:
1、封装数据
主要原因是:保护私隐,明确区分内外。将数据隐藏起来这不是目的。隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制。
class people:
def __init__(self,name,age):
self.__name=name
self.__age=age
def print_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
obj = people('jasn',18)
obj.print_info() #结果为:姓名:jasn, 年龄:18
obj.set_info('金鞍少年', 19) # 对修改内容进行限制,规避掉sql注入的可能
obj.print_info() # 结果为:姓名:金鞍少年, 年龄:19
2、降低复杂度
文章开头就讲到封装的一大特点:就是将复杂的信息、流程给包起来,内部处理,让使用者只需要通过简单的操作步骤,就能实现。
#取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
#对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做隔离了复杂度,同时也提升了安全性
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()
a=ATM()
a.withdraw()
4、封装的特性
1、@property方法
Python内置的@property装饰器就是负责把一个方法变成属性
案例一
'''
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__(self, name, height, weight):
self.__name = name
self.__height = height//10
self.__weight = weight
@property
def bmi(self):
BMI = self.__weight / (self.__height ** 2)
return '{:.2f}%' .format(BMI * 100)
obj = People('金鞍少年', 179, 67)
print(obj.bmi)
案例二
# 我们知道一个人年龄必须是整数,而且是有范围限制的。
class People:
def __init__(self,name, age):
self.name = name
self.__age = age
@property # 负责查询
def age(self):
return self.__age
@age.setter # 对修改年龄加以限制
def age(self, value):
if not isinstance(value, int): # 在设定值之前进行类型检查,增加限制的扩展性
raise TypeError('年龄必须为整型!')
if value < 0 or value > 120:
raise TypeError('年龄超出范围!')
self.__age = value
@age.deleter # 删除属性接口
def age(self):
del self.__age # del self.age
obj = People('jasn', 18)
print(obj.age)
obj.age = 99 # 触发age.setter方法
print(obj.age)
del obj.age
print(obj.age) # 删除成功就报错,提示没有
'''
@property的实现比较复杂,我们先考察如何使用。把一个age方法变成属性,只需要加上@property就可以了,
此时,@property本身又创建了另一个装饰器@age.setter,负责把一个age方法变成属性赋值,
于是,我们就拥有一个可控的属性操作来限制age取值范围。
'''
被 property 装饰的属性会优先于对象的属性被使用(找到) 而被 property装饰的属性,分成三种 property 查询 age.setter 赋值,修改 age是方法名 age.deleter 删除 如果对象要修改数据属性的时候,在没有 property 的情况下,可以随便改,但是加了之后就有一个可控的属性操作来限制age取值范围。
[转载] python基础:面向对象-封装相关推荐
- [python基础] 面向对象——封装,继承
面向对象 一.面向对象的基础知识 二.类和面向对象 三.封装 四.继承 (1).基本使用方法 (2).链表相加 (3).多继承 (4).私有属性与私有方法 一.面向对象的基础知识 1.面向对象 定义: ...
- python基础——面向对象的程序设计
python基础--面向对象的程序设计 1 什么是面向对象的程序设计 面向过程的程序设计的核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优 ...
- python基础—面向对象
python基础-面向对象 面向对象 面向过程VS面向对象 类和实例 实例变量和类变量 类的方法 实例方法 静态方法 类方法 面向对象的组合用法 封装.继承和多态 封装 继承 派生 方法的重写 继承注 ...
- 学Python基础面向对象看这一篇文章就够了【全网首推】
目录 面相对象基础语法 目标 01. dir 内置函数(知道) 02. 定义简单的类(只包含方法) 2.1 定义只包含方法的类 2.2 创建对象 2.3 第一个面向对象程序 03. 方法中的 self ...
- Python之 面向对象封装案例
面向对象封装案例 目标 封装 小明爱跑步 存放家具 封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 -- 将 属性 和 方法 封装 到一个抽象的 类 中 外界 使用 类 创建 对象,然后 ...
- 「Python」面向对象封装案例3——士兵突击(需求分析、代码演练)
分装: 封装是面向对象编程的一大特点 面向对象编程的第一步:将属性和方法分装到一个抽象的类中 外界使用类创建对象,然后让对象调用方法 对象方法的细节都被封装在累的内部 注意:一个对象的属性可以是另外一 ...
- Python中面向对象封装案例——小明爱跑步、摆放家具
文章目录 面向对象封装案例 目标 1. 封装 2. 小明爱跑步 2.1 小明爱跑步扩展 -- 小美也爱跑步 3. 摆放家具 3.1 创建家具 3.2 创建房间 3.3 添加家具 3.4 小结 面向对象 ...
- python基础----面向对象的程序设计(五个阶段、对小白的忠告、关于OOP常用术语)、类、对象...
一.面向对象的软件开发有如下几个阶段 1.面向对象分析(object oriented analysis ,O ...
- Python基础(封装、继承、多态)
面向对象的三大特征:封装.继承.多态 封装 概念:将一个对象的数据隐藏在对象内部,不让在外界直接访问,而是通过对象提供的方法来访问这些隐藏起来的数据,这样就可以在访问方法中添加访问条件限制,目的是对数 ...
最新文章
- 14.PTD与的基址
- mysql ngram_MySQL ngram全文解析器
- 德国80%的统计学教授都会答错的6个与P值有关的问题!
- 图片抓取_小小爬虫批量抓取微信推文里的图片
- wpf,后台触发按钮点击以及拖动
- Xenon构建MySQL高可用
- 网站通用 敏感词列表
- HTML零基础入门教程(详细)
- python如何获取excel数据_python如何读取excel表数据
- 苹果电脑Chrome浏览器截网页长图
- 云更新服务器更新不了最新游戏,云更新服务器环境要求 | 专业网吧维护
- 前台、后台、前端、后端的区分
- 多路输出开关电源的设计及应用原则
- linux系统下 USB 摄像头1080分辨率采集帧率低问题的解决方法
- 2019年8月,微信朋友圈发长文字防止被折叠成一行的方法
- L1-020. 帅到没朋友(2016)
- 2020安徽省大学生程序设计大赛题解——A数字排列
- 关于浅拷贝、深拷贝的探究
- 设任意n个整数存放于数组A[1..n]中,试编写算法,将所有正数排在所有负数前面(要求:算法时间复杂度为O(n))。
- AJAX基础入门实例教程(含代码)
热门文章
- 【代码模板】不存在的NOIP2016
- android 文件流转换为zip文件_PDF文件如何转换为TXT文本?教您一招高效转换的方法...
- Python入门--字典元素的遍历for-in
- @cacheable 服务器 不一致_Dubbo一致性哈希负载均衡的源码和Bug,了解一下?
- 数据结构—平衡二叉树
- 5.顺序表和链表的最值,逆置和归并有序表
- [leetcode] 96. 不同的二叉搜索树 +[补充] 不同的二叉树,不同形态的二叉树的个数----catalan数
- 基础Floyd--任意两点间最短路
- 用法getline(cin,a)和cin.getline(a,20) 能将空格输出
- hue安装使用,集成数据库