Python 面向对象——6.封装

本章学习链接如下:

Python 面向对象——1.基本概念

Python 面向对象——2.类与对象实例属性补充解释,self的作用等

Python 面向对象——3.实例方法,类方法与静态方法

Python 面向对象——4.继承

Python 面向对象——5.多态

1. 封装的基本概念

封装是将属性和方法结合在一起的机制,同时限制对对象内部实现的直接访问。在Python中,封装通常是通过定义类和使用私有变量(以双下划线开头)来实现的。封装的主要目的是隐藏对象的内部状态和复杂性,只暴露出一个清晰和简洁的接口供外部代码使用。

(1)私有变量

私有变量是一种访问限制机制,用于限制类外部对类内部属性或方法的直接访问。

命名约定:在Python中,私有变量通常以两个下划线(_ _)开头。例如:_ _my_variable。那这是怎样做到的呢?源于Python中的名称重整机制。

(2)名称重整规则 

  1. 如果属性名以双下划线开头,但不以下划线结尾(_ _name),那么在名称重整时,会将属性名中的双下划线替换为类名,然后再加上一个单下划线。例如,对于类MyClass中的属性_ _my_variable,重整后的名称将是_MyClass_ _my_variable

  2. 如果属性名以双下划线开头,并且以下划线结尾(_ _my_variable_ _),那么在名称重整时,会保留一个下划线在属性名的开头和结尾。例如,对于类MyClass中的属性_ _my_variable_ _,重整后的名称将是 _MyClass_ _my_variable_ _

我们看下面这个代码示例,self._ _salary 是一个私有属性,它被声明为私有的,因为它的名称以双下划线开头。根据名称重整规则,这个属性在类外部的名称将变为 _Employee_ _salary。self._ _top_secret() 是一个私有方法,同样因为以双下划线开头,它在类外部的名称将变为 _Employee_ _top_secret。当我们尝试直接访问这些私有成员时,Python解释器会抛出一个 AttributeError,因为它找不到这些属性或方法。然而,如果我们知道了名称重整后的名称,我们仍然可以访问到这些私有成员,但这违反了封装的原则,因此通常不推荐这样做。

请注意,尽管我们可以通过名称重整后的名称访问私有成员,但这并不是Python推崇的做法。更好的做法是通过类的公有接口(如方法)来访问或修改私有成员,以保持类的封装性。

class Employee:def __init__(self, name):self.name = name  # 公开属性self.__salary = 50000  # 私有属性,使用双下划线开头def give_raise(self, amount):self.__salary += amountprint(f"{self.name}'s new salary is: ${self.__salary}")def __top_secret(self):pass  # 私有方法,使用双下划线开头# 创建Employee类的实例
emp = Employee("Alice")# 尝试直接访问私有属性(这将不会成功)
try:print(emp.__salary)  # 错误:__salary不是Employee的属性
except AttributeError as e:print(e)# 尝试调用私有方法(这也将不会成功)
try:emp.__top_secret()  # 错误:__top_secret不是Employee的方法
except AttributeError as e:print(e)# 使用公开方法访问私有属性
print(f"{emp.name}'s salary is: ${emp._Employee__salary}")

请注意,名称重整并不是真正的私有化,而是一种约定。它通过名称改写来减少属性被外部访问的可能性,但并不阻止有经验的程序员绕过这个机制。在Python中,如果你想要完全私有的属性,可以使用单下划线开头的属性名(_my_variable),但这只是一种约定,表示该属性不应该被外部直接访问。

(3)try:

tryexcept语句用于异常处理。当你执行一个可能会抛出异常的代码段时,可以将该段代码放在try块中。如果在try块中的代码执行过程中发生了异常,程序的执行将不会立即停止,而是会跳转到except块中,这允许你捕获并处理异常。

在这段代码示例中,try块用于尝试访问Employee类的私有属性_ _salary和调用私有方法_ _top_secret。根据Python的命名规则,以双下划线开头的属性和方法对外部是不可访问的,因为它们被视为私有的(尽管这不是一种真正的私有机制,只是一种命名约定)。

代码中的两个try块尝试执行如下操作:

  1. 尝试直接访问emp实例的私有属性_ _salary。由于_ _salary是私有的,这个尝试会抛出AttributeError,因为_ _salary不是Employee实例的公开属性。

  2. 尝试调用emp实例的私有方法_ _top_secret。同样,由于_ _top_secret是私有的,这个尝试也会抛出AttributeError

2.错误捕获

(1)背后的原理

except AttributeError as e:print(e)

 当AttributeError被捕获时,变量e是一个异常对象。这个对象包含了异常的详细信息,当你打印e时,实际上是调用了该对象的__str__()方法,它返回异常的描述性字符串。

当你打印一个异常对象时,背后实际上是调用了该对象的__str__()方法。这是Python对象的内置特殊方法(也称为"dunder"方法,即双下划线前缀和后缀的方法),用于返回对象的字符串表示形式。即使在给定的类定义中没有显式地看到__str__()方法,它也是隐式存在的,因为所有的Python对象默认继承自object类,而object类提供了一个默认的__str__()实现。

异常类(如AttributeError)通常会重写__str__()方法,以返回一个描述错误的字符串。当你执行print(e),Python首先查找对象e__str__()方法,并调用它来获取字符串表示,然后打印出来。

这是Python中所有异常对象的标准行为,所以即使你在类定义中没有看到显式的__str__()方法,当你打印异常对象时,它也是可用的。

下面是一个简单的示例,展示如何自定义一个类并重写__str__()方法:

在上面的代码中,我们创建了一个自定义异常MyError,它继承自Python的基类Exception。我们重写了__str__()方法来返回一个自定义的错误信息。当异常被捕获并打印时,会显示我们提供的信息。

class MyError(Exception):def __str__(self):return "自定义错误信息"try:raise MyError()
except MyError as e:print(e)  # 输出: 自定义错误信息

(2)Exception

Python的Exception类是所有内置和用户定义的异常的基类。它位于异常类继承层次结构的顶端,提供了处理异常时的默认行为。在Python中,异常是用于错误处理的一种机制,允许程序在发生错误时从代码的某个部分“跳出”,并提供一种方式来响应或恢复。

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

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

相关文章

unity cinemachine相机 (案例 跟随角色移动)

安装相机包 打开包管理工具 在 unity registry 搜索cinemachine 会在maincamera中生成一个组件cinemachineBrain 只能通过虚拟相机操控 主相机 虚拟相机的参数 案例 1.固定相机效果 位置 在固定的地方 默认的模式 2.相机跟随人物效果 焦距设置 20 跟随设置 把playere…

使用Tortoise 创建远程分支

1。首先创建本地分支branch1,右键tortoise git->创建分支,输入分支名称branch1,确定。 2。右键tortoise git->推送,按下图设置,确定,git会判断远程有没有分支branch1,如果没有会自动创建…

重看Spring聚焦Environment分析

目录 一、理解Environment的设计 (一)整体理解 (二)聚焦Profiles分析 (三)聚焦Properties分析 二、Environment类图结构分析 三、PropertyResolver源码分析 (一)源码展示说明…

C语言学习/复习36

一、程序的环境与预处理 二、翻译环境与执行环境 三、运行环境 四、预编译(预处理)详解

mac电脑搭建vue环境(上篇)

第一步:mac电脑要有homebrew,如何安装homebrew 点击下方 MAC安装homebrew-CSDN博客 第二步:homebrew安装node.js 第三步:安装npm 第四步:安装webpack 第五步:安装vue脚手架 第六步:可以在…

NumPy 1.26 中文官方指南(一)

NumPy 用户指南 原文:numpy.org/doc/1.26/user/index.html 本指南是一个概述,解释了重要特性;细节请参阅 NumPy 参考文档。 入门指南 什么是 NumPy? 安装 NumPy 快速入门 NumPy:初学者的绝对基础 基础知识和用法 NumPy 基础…

工信部绿色工厂、绿色设计产品、绿色供应链企业、绿色园区名单数据集(2017-2022年)

01、数据简介 工信部致力于推动制造业的绿色转型,为了表彰在绿色制造领域取得显著成绩的企业和园区,工信部发布了绿色工厂公示名单、绿色设计产品公示名单、绿色供应链企业公示名单和绿色园区公示名单。 这些企业和园区在绿色制造方面做出了卓越的贡献…

MySQL__锁

文章目录 😊 作者:Lion J 💖 主页: https://blog.csdn.net/weixin_69252724 🎉 主题: MySQL__锁) ⏱️ 创作时间:2024年04月27日 ———————————————— 这里写目录…

刷题训练之前缀和

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟练掌握前缀和算法。 > 毒鸡汤:学习,学习,再学习 ! 学,然后知不足。 > 专栏选自:刷题…

【Hadoop】-HDFS的存储原理[4]

目录 前言 一、fsck命令 1、HDFS副本块数量的配置 2、fsck命令查看文件的副本数 3、block配置 二、NameNode元数据 1、edits文件 2、fsigame文件 3、NameNode元数据管理维护 4、元数据合并控制参数 5、SecondaryNameNode的作用 三、HDFS数据的读写流程 1、数据写入…

Pytorch 之torch.nn初探 卷积--Convolution Layers

任务描述 本关任务: 本关提供了一个Variable 类型的变量input,按照要求创建一 Conv1d变量conv,对input应用卷积操作并赋值给变量 output,并输出output 的大小。 相关知识 卷积的本质就是用卷积核的参数来提取原始数据的特征&a…

前端HTML5学习1(新增布局,状态,列表,文本,表单控件标签)

前端HTML5学习1(新增布局,状态,列表,文本,表单控件标签) 新增布局标签新增状态标签新增列表标签新增文本标签新增表单控件属性input新增属性值 新增布局标签 HTML5 引入了许多新的语义化标签,用…

【MySQL】A01、性能优化-参数监控分析

1、参数监控 1.1、MySQL command 查看 mysql>SHOW STATUS; (服务器状态变量,运行服务器的统计和状态指标) mysql> SHOW VARIABLES;(服务器系统变量,实际上使用的变量的值) mysql> SHOW STATUS …

SpringBoot---------Hutool

第一步&#xff1a;引入依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-parent</artifactId><version>5.7.17</version></dependency> 第二步&#xff1a;各种用法 ①生成随机数 //生成验证码 String s …

Linux磁盘管理与文件系统

目录 一.磁盘基础 磁盘结构 二.MBR 磁盘分区结构 三.文件系统类型 XFS文件系统 SWAP&#xff0c;交换文件系统 四.磁盘分区 linux系统添加并使用新硬盘的步骤 五 .创建文件系统 mkfs mkfs命令 挂载、卸载文件系统 挂载文件系统、ISO镜像到指定文件夹 ​编辑umount…

Redis可视化工具RedisInsight

下载地址&#xff1a;RedisInsight - The Best Redis GUIRedisInsight provides an intuitive and efficient graphical interface for Redis, allowing you to interact with your databases and manage your data.https://redis.com/redis-enterprise/redis-insight/#insight…

IDEA上配置Maven环境

1.选择IDEA中的Setting 2.搜索maven 3.设置IDEA使用本地安装的Maven&#xff0c;并修改配置文件路径 配置文件&#xff0c;本地仓库&#xff0c;阿里云仓库配置及路径教程 在IDEA上配置完成。

【Linux内核驱动基础】从零开始手搓一个从上层应用到底层驱动的IO口代码

【Linux内核驱动基础】从零开始手搓一个从上层应用到底层驱动的IO口控制代码 文章目录 【Linux内核驱动基础】从零开始手搓一个从上层应用到底层驱动的IO口控制代码一、驱动基础认知1.为什么要学会写驱动2.文件名与设备号3.open函数从上层打通到底层硬件的详细过程 二、基于内核…

【强训笔记】day4

NO.1 思路&#xff1a;利用滚动数组&#xff0c;迭代一个Fibonacci数列&#xff0c;给出三个值进行循环迭代&#xff0c;当n<c时&#xff0c;说明n在b和c之间&#xff0c;这里只需要返回c-n和n-b的最小值就可以了。 代码实现&#xff1a; #include<iostream>using n…