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把对象作为程序的基本单元,一个对象包含了数据和操作 ...
 
随机推荐
- uiautomator2 入门教程
			
一.前言 在 Android 自动化测试方面,Google 提供了一个基于 Java 开发的库 UiAutomator,基本上支持所有的 Android 事件操作,使用简单. 在此基础上,有大佬开发出 ...
 - selenium定位,操作元素
			
1.定位方式 1.id driver.find_element_by_id('username').send_keys('byhy') 2.name driver.find_element_by_na ...
 - java正则匹配字符串例子
			
import java.util.regex.Matcher;import java.util.regex.Pattern; public class sss { public static void ...
 - 🏆【Java技术专区】「延时队列专题」教你如何使用【精巧好用】的DelayQueue
			
延时队列前提 定时关闭空闲连接:服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之. 定时清除额外缓存:缓存中的对象,超过了空闲时间,需要从缓存中移出. 实现任务超时处理:在网络协议滑动窗口请求 ...
 - dio框架访问云函数参数传递问题(以腾讯云中的云函数为例子)第一部
			
dd云函数其实比较普及,这里以腾讯云的云函数为例,传递参数完成简单的账号注册. 一.第一步先注册腾讯云账号,这里不过多阐述,接着点击 控制台 进入开发者界面.(注意提前进行实名认证) 二.开发者界面如 ...
 - Java 日志框架概述(slf4j / log4j / JUL / Common-logging(JCL) / logback)
			
一.简介 JAVA日志在初期可能官方并没有提供很好且实用的规范,导致各公司或OSS作者选择自行造轮子,这也导致了目前初学者觉得市面上 Java 日志库繁杂的局面. 现在市面流行以 slf4j(Simp ...
 - Vue实现多文件上传功能(前端 + 后端代码)
			
本人业余前端开发,因为公司(很坑)觉得我很牛逼,所以让我前后端一起玩,无奈的我只能磕磕碰碰的研究起了vue. 开发项目的时候,用到文件上传的功能很常见,包括单文件上传和多文件上传,上传各种类型的文件. ...
 - alpakka-kafka(7)-kafka应用案例,消费模式
			
上篇描述的kafka案例是个库存管理平台.是一个公共服务平台,为其它软件模块或第三方软件提供库存状态管理服务.当然,平台管理的目标必须是共享的,即库存是作为公共资源开放的.这个库存管理平台是一个Kaf ...
 - MySQL学习02(操作数据库)
			
操作数据库 结构化查询语句分类 名称 解释 命令 DDL(数据库定义语言) 定义和管理数据对象,例如数据库和数据表 create.drop.alter DML(数据操作语言) 用于操作数据库对象中所包 ...
 - Linux 文件、目录与磁盘格式
			
文件属性 连接数 文件持有者 文件所属群组 文件容量 文件最后修改时间 文件名(就那个..) 第一栏其中文件属性有10,第一个属性代表这个文件是目录.文件或链接文件: [d]目录 [-]文 ...