Python - 面向对象编程 - @property
前言
- 前面讲到实例属性的时候,我们可以通过 实例对象.实例属性 来访问对应的实例属性
- 但这种做法是不建议的,因为它破坏了类的封装原则
- 正常情况下,实例属性应该是隐藏的,只允许通过类提供的方法来间接实现对实例属性的访问和操作
- class PoloBlog:
- # 构造方法
- def __init__(self, name):
- self.name = name
- blog = PoloBlog("小菠萝")
- # 破坏了封装原则
- print(blog.name)
- blog.name = "啊?"
- print(blog.name)
- # 输出结果
- 小菠萝
- 啊?
getter、setter 方法
- 不破坏类封装原则的基础上,操作实例属性
- 写过 java 的话应该知道,java 的类可以自动生成对属性的操作方法,一个是 get,另一个是 set(一般称为 getter、setter 方法)
- python 中虽然不能自动生成,但也可以自己写哦
- class PoloBlog:
- # 构造方法
- def __init__(self, name):
- self.name = name
- # set 属性的方法【setter】
- def setName(self, name):
- self.name = name
- # get 属性的方法【getter】
- def getName(self):
- return self.name
- blog = PoloBlog("小菠萝")
- # 获取 blog 实例对象的 name 实例属性
- print(blog.getName())
- # 设置 name 实例属性
- blog.setName("新的小菠萝")
- print(blog.getName())
- # 输出结果
- 小菠萝
- 新的小菠萝
这样跟 java 的写法就差不多了,但还是有点麻烦
property() 方法的诞生
可以实现在不破坏类封装原则的前提下,让开发者依旧使用 对例对象.属性 的方式操作类中的属性
基本使用格式
- 属性名 = property(fget=None, fset=None, fdel=None, doc=None)
- fget:用于获取属性的方法
- fset:用于设置属性的方法
- fdel:用于删除属性的方法
- doc:属性的说明文档字符串
代码栗子
- # property() 函数
- class PoloBlog:
- # 构造函数
- def __init__(self, name):
- self.__name = name
- # setter
- def setName(self, name):
- self.__name = name
- # getter
- def getName(self):
- return self.__name
- # del
- def delName(self):
- self.__name = "xxx"
- # property()
- name = property(getName, setName, delName, "小菠萝测试笔记")
- # 调用说明文档
- # help(PoloBlog.name)
- print(PoloBlog.name.__doc__)
- blog = PoloBlog("小菠萝")
- # 自动调用 getName()
- print(blog.name)
- # 自动调用 setName()
- blog.name = "新的小菠萝"
- print(blog.name)
- # 自动调用 delName()
- del blog.name
- print(blog.name)
- # 输出结果
- 小菠萝测试笔记
- 小菠萝
- 新的小菠萝
- xxx
getName return 的是私有属性 __name,注意不是 name,不然会陷入死循环
注意
property() 方法的四个参数都是默认参数,可以不传参
- # property() 函数
- class PoloBlog:
- # 构造函数
- def __init__(self, name, age):
- self.__name = name
- self.__age = age
- # setter name
- def setName(self, name):
- self.__name = name
- # getter name
- def getName(self):
- return self.__name
- # del name
- def delName(self):
- self.__name = "xxx"
- # setter age
- def setAge(self, age):
- self.__age = age
- # getter age
- def getAge(self):
- return self.__age
- # property()
- name = property(getName, setName, delName, "小菠萝测试笔记")
- # 没有 fdel、doc
- age = property(getAge, setAge)
- blog = PoloBlog("小菠萝", 14)
- print(blog.age)
- blog.age = "24"
- print(blog.age)
- del blog.age
- print(blog.age)
- # 输出结果
- 14
- 24
- del blog.age
- AttributeError: can't delete attribute
因为 property() 没有传 fdel 方法,所以无法删除属性,它是一个可读写,不可删的属性
其他传参解析
- name = property(getName) # name 属性可读,不可写,也不能删除
- name = property(getName, setName,delName) #name属性可读、可写、也可删除,就是没有说明文档
@property
- 是一个装饰器,相当于 getter 装饰器
- 可以使用 @property 来创建只读属性,将一个实例方法变成一个相同名称的只读属性,这样可以防止属性被修改
代码栗子
- # @property
- class PoloBlog:
- def __init__(self, name):
- self.__name = name
- @property
- def name(self):
- return self.__name
- blog = PoloBlog("小菠萝")
- print(blog.name)
- blog.name = "test"
- # 输出结果
- 小菠萝
- blog.name = "test"
- AttributeError: can't set attribute
name 是一个只读属性,不可写,相当于 __name 私有属性只有 getter 方法,没有 setter 方法
等价写法
- class PoloBlog:
- def __init__(self, name):
- self.__name = name
- def getName(self):
- return self.__name
- name = property(getName)
- blog = PoloBlog("小菠萝")
- print(blog.name)
那想给 __name 设置值怎么办呢?
setter 装饰器
语法格式
- @方法名.setter
- def 方法名(self, value):
- self.__value = value
- ...
代码栗子
- # @setter
- class PoloBlog:
- def __init__(self, name):
- self.__name = name
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, name):
- self.__name = name
- blog = PoloBlog("小菠萝")
- # 打印属性值
- print(blog.name)
- # 修改属性
- blog.name = "新的小菠萝"
- print(blog.name)
- # 输出结果
- 小菠萝
- 新的小菠萝
deleter 装饰器
和 setter 装饰器差不多写法
语法格式
- @方法名.deleter
- def 方法名(self):
- ...
代码栗子
- class PoloBlog:
- def __init__(self, name):
- self.__name = name
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, name):
- self.__name = name
- @name.deleter
- def name(self):
- print("删除 __name")
- blog = PoloBlog("小菠萝")
- # 打印属性值
- print(blog.name)
- # 修改属性
- blog.name = "新的小菠萝"
- # 删除属性
- del blog.name
- # 输出结果
- 小菠萝
- 删除 __name
Python - 面向对象编程 - @property的更多相关文章
- python面向对象编程进阶
python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- python 面向对象编程(一)
一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...
- Python面向对象编程指南
Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...
- Python面向对象编程(下)
本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...
- Python 面向对象编程——访问限制
<无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...
- Python 面向对象编程 继承 和多态
Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...
- Python 面向对象编程基础
Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...
- python面向对象编程学习
python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...
随机推荐
- 手写一个超简单的Vue
基本结构 这里我根据自己的理解模仿了Vue的单文件写法,通过给Vue.createApp传入参数再挂载元素来实现页面与数据的互动. 其中理解不免有错,希望大佬轻喷. 收集数据 这里将Vue.creat ...
- bootstrap与vue的区别是什么?(十七)
Bootstrap Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML.CSS.JavaScript 开发的简洁.直观.强悍的前端开发框 ...
- Matplotlib不能显示中文和正负号的问题
参考链接:https://www.jianshu.com/p/240ea3ae0dc9 在使用matplotlib画饼状图时,遇到了如下问题 UserWarning: findfont: Font f ...
- 开源低代码平台开发实践二:从 0 构建一个基于 ER 图的低代码后端
前后端分离了! 第一次知道这个事情的时候,内心是困惑的. 前端都出去搞 SPA,SEO 们同意吗? 后来,SSR 来了. 他说:"SEO 们同意了!" 任何人的反对,都没用了,时代 ...
- form 表单提交的另一种方式 js
<html> <head> <script type="text/javascript"> function formSubmit() { fm ...
- 线性反馈移位寄存器(LFSR)
LFSR用于产生可重复的伪随机序列PRBS,该电路有n级触发器和一些异或门组成,如下图所示. 其中,gn为反馈系数,取值只能为0或1,取为0时表明不存在该反馈之路,取为1时表明存在该反馈之路:这里的反 ...
- 自学linux——15.云主机的购买流程及域名的购买备案解析
项目上线流程 一.服务器选配购买 项目上线的服务器必须是外网服务器 1.服务器购买情况 真实服务器(成本过高,购买内部自用) 云服务器(上线首选):阿里云,腾讯云,华为云 2.购买阿里云服务器:htt ...
- PPT学习总结
[一]关注 1. 内容 2. 结构 3. 配色 4. 素材 5. 构图 6. 动画 [二]技巧 1. 颜色对比 2. 动画突出 [三]参考 https://www.zhihu.com/question ...
- js原始数据类型有哪些,引用数据类型有哪些
js的数据类型划分方式为 原始数据类型和 引用数据类型 栈: 原始数据类型(Undefined,Null,Boolean,Number.String) 堆: 引用数据类型(对象.数组.函数) 两种类型 ...
- 两年Android开发三面上岸腾讯,这些核心知识点建议收藏
概述 感觉毕业后时间过得真快啊,从 19 年 7 月本科毕业入职后,到现在快两年了,前段时间金三银四期间想着找一个新的工作,前前后后花了一个多月的时间复习以及面试,面试好几家大厂,最后选择了腾讯.也祝 ...