030.Python面向对象_类补充_只读属性

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈

分隔线

类&补充_只读属性

    • 只读属性
      • 概念
      • 应用场景
      • 实现方法
        • 方式一:使用property装饰器
        • 方式二:使用__setattr__方法进行判断
    • 补充_装饰器property详解
      • property作用
      • property源码
      • 补充:经典类和新式类
      • property在两种类中的使用方式
        • property在新式类中的使用方式
        • property在经典类中的使用方式(在Python2.x版本中运行)

只读属性

概念

  • 一个属性(一般指实例属性),只能读取,不能写入

应用场景

  • 有些属性,只限在内部根据不同场景进行修改,对外界来说,不能修改,只能读取

实现方法

方式一:使用property装饰器
  • 步骤
    • 1、通过私有化全部隐藏(既不能读,也不能写)
    • 2、通过方法部分公开(公开读的操作)
  • 示例
    class Person:def __init__(self):self.__age = 18def getAge(self):return self.__agep = Person()# print(p.__age)          # 报错,通过属性私有化,隐藏了读操作
    # p.__age = 22            # 并不是修改的私有属性,而是新增了__age属性。通过属性私有化,隐藏了写操作print(p.getAge())       # 通过指定方法,公开读操作
    
  • 存在问题
    • 1、获取属性的时候需要通过调用方法获取p.getAge(),而不是通过属性获取方式获取p.age
    • 2、在外部直接使用赋值p.age = 22 并不会报错(虽然没有修改内部的私有属性,而是给实例添加了一个age属性,但是给人的感觉就是修改了)
  • 优化
    class Person:def __init__(self):self.__age = 18# @property的作用:装饰器,可以使用属性的方式调用这个方法@propertydef age(self):return self.__agep = Person()print(p.age)        # 18
    # p.age = 22          # 报错,AttributeError: can't set attribute
    
  • 通过优化之后,就可以通过调用属性的方式调用读属性方法了。并且,外部也不能对这个属性方法进行赋值
  • 缺陷
    • 通过装饰器的方式设置的只读属性,其实还是可以通过 _Person__age 这种改名之后的方式进行修改
    • 也可以通过 实例.__dict__['_Person__age'] = 新值 的方式修改这个只读属性的值
方式二:使用__setattr__方法进行判断
  • 步骤
    • 当通过 实例.属性=值 的方式给实例添加一个属性或修改属性的值时候,会自动调用该方法
    • 在这个方法内部,增加判定方法,满足条件后才把这个属性添加到 __dict__ 这个字典中
  • 代码说明
    class Person(object):# 当通过 实例.属性=值 的方式给实例添加一个属性或修改属性的值时候,会自动调用该方法# 在这个方法内部,才会真正的把这个属性添加到 __dict__ 这个字典中def __setattr__(self, key, value):# key:属性   value:属性值print(key, value)p = Person()
    p.age = 12          # age 12
    
  • 使用__setattr__设置只读属性
    class Person(object):def __init__(self):self.__age = 18pass@propertydef age(self):return self.__age# 当通过 实例.属性=值 的方式给实例添加一个属性或修改属性的值时候,会自动调用该方法# 在这个方法内部,才会真正的把这个属性添加到 __dict__ 这个字典中def __setattr__(self, key, value):# key:属性   value:属性值# print(key, value)if key == 'age':print('隐藏属性,不可修改', key)return# self.key = value# 不能这么写,这样写也是通过 实例.属性=值 的方式给实例添加一个属性或修改属性的值,会循环调用__setattr__方法,出现死循环# 只能通过下面的方法给实例添加/修改属性self.__dict__[key] = valuep = Person()
    print(p.age)            # 18
    p.age = 22              # 隐藏属性,不可修改 age
    print(p.age)            # 18

补充_装饰器property详解

property作用

  • 将一些“属性的操作方法(删、改、查)”关联到某一个属性中
class Person(object):def __init__(self):self.__age = 18@property    def age(self, num):"""属性的操作方法:获取属性值"""return self.__age

property源码

  • preoperty源码说明
    class property(object):"""Property attribute.property(fget=None, fset=None, fdel=None, doc=None) -> property ottribute# 调用property函数,传入四个参数,返回一个属性# 作用:将一个属性的几个操作方法(删、改、查)关联到返回的这个属性里面# 读取这个属性的时候会自动调用第一个参数:fget方法# 设置这个属性的值会自动调用第二个参数:fset方法# 删除合格属性的时候会自动调用第三个参数:fdel方法fgetfunction to be used for getting an attribute value# 用于获取属性值的函数fsetfunction to be used for setting an attribute value# 用于设置属性值的函数fdelfunction to be used for del'ing an attribute# 用于删除属性值的函数docdocstringTypical use is to define a managed attribute x:# 典型的用法是定义一个定义和管理一个属性x:class C(object):def getx(self): return self._xdef setx(self, value): self._x = valuedef delx(self): del self._xx = property(getx, setx, delx, "I'm the 'x' property.")Decorators make defining new properties or modifying existing ones easy:# 装饰器使定义新属性或修改现有属性变得容易:class C(object):@propertydef x(self):"I am the 'x' property."return self._x# 必须先开启上面的@property装饰器@x.setterdef x(self, value):self._x = value@x.deleterdef x(self):del self._x"""
    

补充:经典类和新式类

  • 经典类
    • 概念:没有继承自object的类
  • 新式类
    • 概念:继承自object的类和其派生类
  • 示例
    # 在Python2.x 版本中
    class Person:passclass Animal(object):pass# 查看基类(父类)
    print(Person.__base__)      # ()
    print(Animal.__base__)      # <class 'object'># ===================================================# 在Python3.x 版本中
    class Person:passclass Animal(object):pass# 查看基类(父类)
    print(Person.__base__)      # <class 'object'>
    print(Animal.__base__)      # <class 'object'>
    
  • 在Python2.x版本中
    • 定义一个类的时候,没有显示的继承自object类,那么这个类就是一个经典类
    • 必须显示的继承自object类,才是一个新式类
  • 在Python3.x版本中
    • 定义一个类的时候,没有显示的继承自pbject类时,会隐式的(默认)继承自object类,这个类就是一个新式类
    • 在通常情况下,我们一般都写成显示继承(即:定义的类继承自object时,也用class Person(object)的方式定义)

property在两种类中的使用方式

property在新式类中的使用方式
  • 使用方式一
    class Person(object):def __init__(self):# 定义一个属性__ageself.__age = 18def get_age(self):"""定义一个__age属性的操作方法(查)"""print('执行get_age方法')return self.__agedef set_age(self, num):"""定义一个__age属性的操作方法(改)"""print('执行set_age方法')self.__age = num# 调用property方法,使age属性与get_age、set_age方法进行关联# 在获取age属性的值时,自动调用property函数的第一个参数:get_age方法# 在设置age属性的值时,自动调用property函数的第二个参数:seg_age方法age = property(get_age, set_age)p = Person()
    print(p.age)        # 执行get_age方法  18p.age = 36          # 执行set_age方法
    print(p.age)        # 执行get_age方法  36print(p.__dict__)   # {'_Person__age': 36},可以看出来,赋值方式并没有给对象增加新的属性,而是直接修改了原本的属性值
    
  • 使用方式二
    class Person(object):def __init__(self):self.__age = 18@propertydef age(self):print("执行了@property装饰的age方法")return self.__age@age.setterdef age(self, num):print("执行了@age.setter装饰的age方法")self.__age = num@age.deleterdef age(self):print("执行了@age.deleter装饰的age方法")del self.__agep = Person()
    print(p.age)        # 执行了@property装饰的age方法  18p.age = 36          # 执行了@age.setter装饰的age方法print(p.__dict__)   # {'_Person__age': 36}del p.age           # 执行了@age.deleter装饰的age方法
    
property在经典类中的使用方式(在Python2.x版本中运行)
  • 使用方式一
    # Python2.x版本运行
    # 定义一个经典类,不继承自object类
    class Person:def __init__(self):self.__age = 18def get_age(self):print '执行了get_age方法'return self.__agedef set_age(self, num):print '执行了set_age方法'self.__age = numage =property(get_age, set_age)p = Person()
    print p.age        # 执行了get_age方法p.age = 36          # print(p.__dict__)   # {'age': 36, '_Person__age': 18}# 可以看出来,在经典类中,属性的赋值操作并不能关联到property函数的第二个参数
    
  • 使用方式二
    # Python2.x版本运行
    # 定义一个经典类,不继承自object类
    class Person:def __init__(self):self.__age = 18@propertydef age(self):print '执行了get_age方法'return self.__age@age.setterdef age(self, num):print '执行了set_age方法'self.__age = nump = Person()
    print p.age        # 执行了get_age方法  18p.age = 36          #print(p.__dict__)   # {'age': 36, '_Person__age': 18}
    
  • 通过示例可以看出来,在经典类中,虽然我们可以定义装饰属性赋值操作的方法,但是并不能真正的将这个操作方法与赋值操作进行关联

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/124856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB中perceptron函数用法

目录 语法 说明 示例 使用感知器求解简单分类问题 perceptron函数的功能是简单的单层二类分类器。 语法 perceptron(hardlimitTF,perceptronLF) 说明 注意 Deep Learning Toolbox™ 支持早期形式的感知器。为了获得更好的结果&#xff0c;您应改用 patternnet&#xff0…

【Linux】-进程控制(深度理解写时拷贝、exit函数、return的含义以及makefile编译多个程序)-进程创建、进程终止、进程等待、进程程序替换

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

【华为】路由器以PPPoE拨号接入广域网

组网需求 用户希望以PPPoE拨号方式接入广域网&#xff0c;如图1所示&#xff0c;Router作为PPPoE客户端&#xff0c;得到PPPoE服务器的认证后获得IP地址&#xff0c;实现用户接入互联网的需求。内网网关地址&#xff08;即VLANIF1接口的IP地址&#xff09;为10.137.32.1/24。 …

JVS-BI数字大屏设计器:一站式解决方案

数字大屏介绍 数字大屏是当下数据展示、业务监控、指挥调度常见的业务表达形态&#xff0c;常有可视化的图表、效果装饰、事件操作等技术组成酷炫的效果展示。 配置入口 进入JVS-BI&#xff08;bi.bctools.cn&#xff09;&#xff0c;进入大屏页面&#xff0c;如下图所示 ①…

想翻译pdf文档,试了几个工具对比:有阿里(完全免费,快,好用,质量高,不用注册登录)道最好(有限免费) 百度(有限免费)和谷歌完全免费(网不好)

文档翻释作为基础设施&#xff0c;工作必备。 阿里 &#xff08;完全免费&#xff0c;快&#xff0c;好用&#xff0c;质量高&#xff0c;不用注册登录&#xff0c;无广告&#xff09;我给满分 https://translate.alibaba.com/#core-translation 先选好语言。 Google(完全免…

css position属性与js滚动

“视口”就是浏览器窗口中实际显示文档内容的区域&#xff0c;不包含浏览器的“外框”&#xff0c;如菜单、工具条和标签。文档则是指整个网页。 1 css 的position static 正常定位&#xff0c;是元素position属性的默认值&#xff0c;元素遵循常规流。 relative 相对定位&…

【年终特惠】全流程HEC-RAS 1D/2D水动力与水环境模拟技术案例实践及拓展应用

水动力与水环境模型的数值模拟是实现水资源规划、环境影响分析、防洪规划以及未来气候变化下预测和分析的主要手段。然而&#xff0c;一方面水动力和水环境模型的使用非常复杂&#xff0c;理论繁复&#xff1b;另一方面&#xff0c;免费的水动力和水环境软件往往缺少重要功能&a…

Failed to restart sshd.service: Unit sshd.service not found

Failed to restart sshd.service: Unit sshd.service not found.出现这个问题以及远程链接mobaxterm出现 Network error: Connection refused的解决方案如下 其实出现问题二就是kail2018里面的ssh服务未开启&#xff0c;和问题一是同样的&#xff0c;故汇集写在一篇帖子中&…

【兔子王赠书第4期】用ChatGPT轻松玩转机器学习与深度学习

文章目录 前言机器学习深度学习ChatGPT推荐图书粉丝福利尾声 前言 兔子王免费赠书第4期来啦&#xff0c;突破传统学习束缚&#xff0c;借助ChatGPT的神奇力量&#xff0c;解锁AI无限可能&#xff01; 机器学习 机器学习是人工智能领域的一个重要分支&#xff0c;它的目的是让…

二叉树问题——前/中/后/层遍历(递归与栈)

摘要 博文主要介绍二叉树的前/中/后/层遍历(递归与栈)方法 一、前/中/后/层遍历问题 144. 二叉树的前序遍历 145. 二叉树的后序遍历 94. 二叉树的中序遍历 102. 二叉树的层序遍历 二、二叉树遍历递归解析 // 前序遍历递归LC144_二叉树的前序遍历 class Solution {publi…

2023年CCF中国开源大会“大模型时代的智能化软件工程新范式”分论坛成功举行...

2023年CCF中国开源大会“大模型时代的智能化软件工程新范式”分论坛于10月21日在湖南长沙成功举行。本次论坛聚焦大模型时代的智能化软件新生态以及相应的软件工程新范式&#xff0c;邀请了多位来自学术界和工业界的专家进行分享和交流&#xff0c;共设置了5个主题报告和1个Pan…

SpringBoot SerializationUtils克隆(反序列化) 类加载器不一致问题(ClassCastException)

问题分析 在SpringBoot中使用 org.apache.commons.lang.SerializationUtils.clone 方法时&#xff0c;发现克隆出来的类强转对应类时发生类型不一致的错误&#xff0c;经过检测发现两个看似相同的类的类加载器不一致 场景 报错信息 java.lang.ClassCastException: com.tianq…

OSEK OS介绍(一)

目录 1.OSEK OS架构 2.OSEK Task Management 2.1 Basic task&#xff1a; 2.2 Extended task 2.3 任务状态机 2.4 任务优先级 3.调度策略 3.1 完全抢占策略 3.2 非抢占式调度 3.3 混合式调度 4. Application Mode OSEK&#xff0c;汽车电子开放式系统及其接口&#…

KT6368A蓝牙芯片的4脚也就是蓝牙天线脚对地短路了呢?是不是坏了

一、问题简介 KT6368A芯片的4脚&#xff0c;也就是蓝牙天线脚&#xff0c;万用表测量对地短路了呢&#xff1f;是不是芯片坏掉了&#xff0c;能不能重新寄样品给我。 详细说明 首先&#xff0c;芯片没有坏&#xff0c;遇到自己不懂的地方&#xff0c;不要轻易的去怀疑。 而是…

基于计算机视觉的 Transformer 研究进展

论文地址&#xff1a; https://kns.cnki.net/kcms/detail/11.2127.tp.20211129.1135.004.html 18页&#xff0c;74篇参考文献 目录 摘 要 1 Transformer 基本原理 1.1 编码器-解码器 1.2 自注意力 1.3 多头注意力 2 在计算机视觉领域的应用 2.1 图像分类 2.1.1 iGPT …

无需更换vue-cli 脚手架 uniapp-搭建项目-H5-低版本安卓IOS兼容问题(白屏)(接口请求异常)

✨求关注~ &#x1f4bb;博客&#xff1a;www.protaos.com I. 简介 A. UniApp项目概述 B. 白屏和接口请求异常问题的背景 II. 白屏问题 A. 问题描述 1、uniapp 打包H5内嵌入APP内、低版本手机系统访问白屏问题 B. 问题根本原因 1、低版本手机系统 自带的webview内核不支持ES6语…

C++进阶语法——智能指针【学习笔记(五)】

文章目录 1、智能指针简介1.1 原始指针&#xff08;raw pointer&#xff09;的⼀些问题1.2 智能指针&#xff08;smart pointers&#xff09; 2、智能指针&#xff08;smart pointers&#xff09;——unique_ptr2.1 unique_ptr 的声明2.2 unique_ptr 的函数2.3 ⾃定义类型使⽤ …

0004net程序设计-抗疫物资

文章目录 **摘** **要**目 录系统设计开发环境 摘 要 近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;抗疫物资管理系统利用计算机网络实现信息化管理&#xff0c;使整个抗疫物资管理…

Linux下GPIO和看门狗应用编程

文章目录 GPIO应用编程看门狗应用编程 GPIO应用编程 应用层操控硬件可以通过操作这些硬件的设备文件来进行&#xff0c;设备文件是各种硬件设备向应用层提供的一个接口&#xff0c;应用层通过对设备文件的I/O操作来操控硬件设备。设备文件通常在/dev/目录下&#xff0c;该目录…

Yolo-Z:改进的YOLOv5用于小目标检测

目录 一、前言 二、背景 三、新思路 四、实验分析 论文地址&#xff1a;2112.11798.pdf (arxiv.org) 一、前言 随着自动驾驶汽车和自动驾驶赛车越来越受欢迎&#xff0c;对更快、更准确的检测器的需求也在增加。 虽然我们的肉眼几乎可以立即提取上下文信息&#xff0c;即…