前言

  • 前面讲到实例属性的时候,我们可以通过 实例对象.实例属性 来访问对应的实例属性
  • 但这种做法是不建议的,因为它破坏了类的封装原则
  • 正常情况下,实例属性应该是隐藏的,只允许通过类提供的方法来间接实现对实例属性的访问和操作
  1. class PoloBlog:
  2. # 构造方法
  3. def __init__(self, name):
  4. self.name = name
  5.  
  6. blog = PoloBlog("小菠萝")
  7. # 破坏了封装原则
  8. print(blog.name)
  9. blog.name = "啊?"
  10. print(blog.name)
  11.  
  12. # 输出结果
  13. 小菠萝
  14. 啊?

getter、setter 方法

  • 不破坏类封装原则的基础上,操作实例属性
  • 写过 java 的话应该知道,java 的类可以自动生成对属性的操作方法,一个是 get,另一个是 set(一般称为 getter、setter 方法)
  • python 中虽然不能自动生成,但也可以自己写哦
  1. class PoloBlog:
  2. # 构造方法
  3. def __init__(self, name):
  4. self.name = name
  5.  
  6. # set 属性的方法【setter】
  7. def setName(self, name):
  8. self.name = name
  9.  
  10. # get 属性的方法【getter】
  11. def getName(self):
  12. return self.name
  13.  
  14. blog = PoloBlog("小菠萝")
  15. # 获取 blog 实例对象的 name 实例属性
  16. print(blog.getName())
  17.  
  18. # 设置 name 实例属性
  19. blog.setName("新的小菠萝")
  20.  
  21. print(blog.getName())
  22.  
  23. # 输出结果
  24. 小菠萝
  25. 新的小菠萝

这样跟 java 的写法就差不多了,但还是有点麻烦

property() 方法的诞生

可以实现在不破坏类封装原则的前提下,让开发者依旧使用 对例对象.属性 的方式操作类中的属性

基本使用格式

  1. 属性名 = property(fget=None, fset=None, fdel=None, doc=None)
  • fget:用于获取属性的方法
  • fset:用于设置属性的方法
  • fdel:用于删除属性的方法
  • doc:属性的说明文档字符串

代码栗子

  1. # property() 函数
  2. class PoloBlog:
  3. # 构造函数
  4. def __init__(self, name):
  5. self.__name = name
  6.  
  7. # setter
  8. def setName(self, name):
  9. self.__name = name
  10.  
  11. # getter
  12. def getName(self):
  13. return self.__name
  14.  
  15. # del
  16. def delName(self):
  17. self.__name = "xxx"
  18.  
  19. # property()
  20. name = property(getName, setName, delName, "小菠萝测试笔记")
  21.  
  22. # 调用说明文档
  23. # help(PoloBlog.name)
  24. print(PoloBlog.name.__doc__)
  25.  
  26. blog = PoloBlog("小菠萝")
  27.  
  28. # 自动调用 getName()
  29. print(blog.name)
  30.  
  31. # 自动调用 setName()
  32. blog.name = "新的小菠萝"
  33. print(blog.name)
  34.  
  35. # 自动调用 delName()
  36. del blog.name
  37. print(blog.name)
  38.  
  39. # 输出结果
  40. 小菠萝测试笔记
  41. 小菠萝
  42. 新的小菠萝
  43. xxx

getName return 的是私有属性 __name,注意不是 name,不然会陷入死循环

注意

property() 方法的四个参数都是默认参数,可以不传参

  1. # property() 函数
  2. class PoloBlog:
  3. # 构造函数
  4. def __init__(self, name, age):
  5. self.__name = name
  6. self.__age = age
  7.  
  8. # setter name
  9. def setName(self, name):
  10. self.__name = name
  11.  
  12. # getter name
  13. def getName(self):
  14. return self.__name
  15.  
  16. # del name
  17. def delName(self):
  18. self.__name = "xxx"
  19.  
  20. # setter age
  21. def setAge(self, age):
  22. self.__age = age
  23.  
  24. # getter age
  25. def getAge(self):
  26. return self.__age
  27.  
  28. # property()
  29. name = property(getName, setName, delName, "小菠萝测试笔记")
  30. # 没有 fdel、doc
  31. age = property(getAge, setAge)
  32.  
  33. blog = PoloBlog("小菠萝", 14)
  34.  
  35. print(blog.age)
  36.  
  37. blog.age = "24"
  38. print(blog.age)
  39.  
  40. del blog.age
  41. print(blog.age)
  42.  
  43. # 输出结果
  44. 14
  45. 24
  46. del blog.age
  47. AttributeError: can't delete attribute 

因为 property() 没有传 fdel 方法,所以无法删除属性,它是一个可读写,不可删的属性

其他传参解析

  1. name = property(getName) # name 属性可读,不可写,也不能删除
  2. name = property(getName, setName,delName) #name属性可读、可写、也可删除,就是没有说明文档

@property

  • 是一个装饰器,相当于 getter 装饰器
  • 可以使用 @property 来创建只读属性,将一个实例方法变成一个相同名称的只读属性,这样可以防止属性被修改

代码栗子

  1. # @property
  2. class PoloBlog:
  3. def __init__(self, name):
  4. self.__name = name
  5.  
  6. @property
  7. def name(self):
  8. return self.__name
  9.  
  10. blog = PoloBlog("小菠萝")
  11. print(blog.name)
  12.  
  13. blog.name = "test"
  14.  
  15. # 输出结果
  16. 小菠萝
  17.  
  18. blog.name = "test"
  19. AttributeError: can't set attribute

name 是一个只读属性,不可写,相当于 __name 私有属性只有 getter 方法,没有 setter 方法

等价写法

  1. class PoloBlog:
  2. def __init__(self, name):
  3. self.__name = name
  4.  
  5. def getName(self):
  6. return self.__name
  7.  
  8. name = property(getName)
  9.  
  10. blog = PoloBlog("小菠萝")
  11. print(blog.name)

那想给 __name 设置值怎么办呢?

setter 装饰器

语法格式

  1. @方法名.setter
  2. def 方法名(self, value):
  3. self.__value = value
  4. ...

代码栗子

  1. # @setter
  2. class PoloBlog:
  3. def __init__(self, name):
  4. self.__name = name
  5.  
  6. @property
  7. def name(self):
  8. return self.__name
  9.  
  10. @name.setter
  11. def name(self, name):
  12. self.__name = name
  13.  
  14. blog = PoloBlog("小菠萝")
  15. # 打印属性值
  16. print(blog.name)
  17. # 修改属性
  18. blog.name = "新的小菠萝"
  19. print(blog.name)
  20.  
  21. # 输出结果
  22. 小菠萝
  23. 新的小菠萝

deleter 装饰器

和 setter 装饰器差不多写法

语法格式

  1. @方法名.deleter
  2. def 方法名(self):
  3. ...

代码栗子

  1. class PoloBlog:
  2. def __init__(self, name):
  3. self.__name = name
  4.  
  5. @property
  6. def name(self):
  7. return self.__name
  8.  
  9. @name.setter
  10. def name(self, name):
  11. self.__name = name
  12.  
  13. @name.deleter
  14. def name(self):
  15. print("删除 __name")
  16.  
  17. blog = PoloBlog("小菠萝")
  18. # 打印属性值
  19. print(blog.name)
  20. # 修改属性
  21. blog.name = "新的小菠萝"
  22. # 删除属性
  23. del blog.name
  24.  
  25. # 输出结果
  26. 小菠萝
  27. 删除 __name

Python - 面向对象编程 - @property的更多相关文章

  1. python面向对象编程进阶

    python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...

  2. python 面向对象编程学习

    1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...

  3. python 面向对象编程(一)

    一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...

  4. Python面向对象编程指南

    Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...

  5. Python面向对象编程(下)

    本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...

  6. Python 面向对象编程——访问限制

    <无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...

  7. Python 面向对象编程 继承 和多态

    Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...

  8. Python 面向对象编程基础

    Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...

  9. python面向对象编程学习

    python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...

随机推荐

  1. linux下系统时间和时钟时间

    linux中有关系统时间.时钟时间的命令: 1显示系统时间的命令 ># date 2显示时钟时间的命令 ># clock或hwclock 3系统时间与互联网同步的命令 ># ntpd ...

  2. 在使用TCP协议进行消息发送时,对消息分帧

    成帧与解析 阅读 <java TCP/IP Socket 编程>第三章笔记 成帧技术(frame)是解决如何在接收端定位消息的首尾位置的问题.在进行数据收发时,必须指定消息接收者如何确定何 ...

  3. noip模拟26[肾炎黄·酱累黄·换莫黄]

    \(noip模拟26\;solutions\) 这个题我做的确实是得心应手,为啥呢,因为前两次考试太难了 T1非常的简单,只不过我忘记了一个定理, T2就是一个小小的线段树,虽然吧我曾经说过我再也不写 ...

  4. firewalld详解

    firewalld详解 注:为了便于查看,我把iptables和firewlld的使用总结文档放到了这个链接(下载),这个文档如果有新的内容和更正,我会及时更新. 有需要可以直接下载查看,应该比在博客 ...

  5. PC免费的小说阅读器,可提取章节

    最近自己做了个小说阅读器,就是下面这个东西啦,目前仅支持Window系统: 个人喜欢在电脑.平板上等大屏幕设备上阅读小说或电子书籍.原因其一是屏幕足够大,可以选择更舒服的字体大小:其二是觉得小屏幕看字 ...

  6. ms17-010

    永恒之蓝和ms17-010简介: 永恒之蓝(EternalBLUE)"是Shadow Brokers(影子经纪人)黑客组织公布的一款黑客工具,该工具利用的漏洞也被称为MS17-010漏洞,M ...

  7. SpringCloud升级之路2020.0.x版-9.如何理解并定制一个Spring Cloud组件

    本系列为之前系列的整理重启版,随着项目的发展以及项目中的使用,之前系列里面很多东西发生了变化,并且还有一些东西之前系列并没有提到,所以重启这个系列重新整理下,欢迎各位留言交流,谢谢!~ 我们实现的 S ...

  8. 深入理解jvm-2Edition-Java内存区域

    1.运行时数据区域 Java虚拟机会将内存区域划分为几个区域,每个区域储存不同类型的数据或承担不同的功能. PC,堆-Java堆,栈-虚拟机栈.本地方法栈,方法区.直接内存. 当类被实例化或stati ...

  9. ELK+kafka docker快速搭建+.NetCore中使用

    ELK开源实时日志分析平台.ELK是Elasticsearch,Logstash,Kibana 的缩写. Elasticsearch:是个开源分布式搜索引擎,简称ESLogstash:是一个完全开源的 ...

  10. 01 CTF从0到。。。。

    无意间在前段时间接触到了CTF,感觉很有意思,就参加了个单位的短期培训,并且参加了比赛,也是无意混进了决赛.感觉自己不会的还很多!SO,开始写博客开始刷题,自己很菜,不会C,不会Python,不会汇编 ...