在Python中进行封装

  在Python中,封装是一种面向对象编程(OOP)的特性,它允许我们将数据(属性)和操作这些数据的方法(函数)捆绑在一起,形成一个独立的对象。封装的主要目的是隐藏对象的内部状态,并只通过对象提供的方法来访问和操作这些状态,用于保护对象的数据完整性,并防止外部代码直接访问或修改对象的内部状态。

  Python中的封装可以通过定义类来实现,在类中,我们可以将属性和方法定义为私有(只能在类内部访问)或公有(可以在类外部访问)。

  以下是一个案例,在自创建的Person类,使用双下划线前缀进行标识两个私有属性__name__age,以及四个公有方法get_name()get_age()set_name()set_age(),采用公共方法获取其私有属性,同时对修改私有属性进行了合法性检查,在公共方法修改了属性值后如果某个属性值错误,会进行报错并取消该属性的修改

进行封装了的类:

class Person:  
    def __init__(self, name, age, height, width):  
        # 私有属性,使用双下划线前缀  
        self.__name = name  
        self.__age = age
        self.__height = height
        self.__width = width
  
    # 公有方法,用于获取私有属性的值  
    def get_name(self):  
        return self.__name  
  
    def get_age(self):  
        return self.__age

    def get_height(self):  
        return self.__height

    def get_width(self):  
        return self.__width  
  
    # 公有方法,用于设置私有属性的值  
    def set_name(self, name):  
        self.__name = name  
  
    def set_age(self, age):  
        if age >= 0 and age <= 120:  # 对年龄进行合法性检查  
            self.__age = age  
        else:  
            print("Invalid age!")

    def set_height(self, height):  
        if height >= 0 and height <= 250:  # 对身高进行合法性检查  
            self.__height = height  
        else:  
            print("Invalid height!") 

    def set_width(self, width):  
        if width >= 50 and width <= 500:  # 对体重进行合法性检查  
            self.__width = width  
        else:  
            print("Invalid width!")
  
# 创建Person对象  
person = Person("Alice", 25, 140, 100)  
  
# 通过公有方法访问和修改私有属性  
print(f"name:{person.get_name()}, age:{person.get_age()}, height:{person.get_height()},width:{person.get_width()}")  
person.set_name("Bob")  
person.set_age(-5)
person.set_height(300)
person.set_width(550)  
print(f"name:{person.get_name()}, age:{person.get_age()}, height:{person.get_height()},width:{person.get_width()}")  
 

这里可以看到age(-5)、width(550)、height(300)这三个错误的属性值进行了报错并取消了修改

name:Alice, age:25, height:140,width:100
Invalid age!
Invalid height!
Invalid width!
name:Bob, age:25, height:140,width:100

未进行封装的类:

直接使用公共类并访问和修改属性

class Person:    
    def __init__(self, name, age, height, width):    
        self.name = name    
        self.age = age  
        self.height = height  
        self.width = width  
  
# 创建Person对象    
person = Person("Alice", 25, 140, 100)    
    
# 直接访问和修改属性    
print(f"name:{person.name}, age:{person.age}, height:{person.height}, width:{person.width}")    
person.name = "Bob"    
person.age = 30  
person.height = 160  
person.width = 200  
print(f"name:{person.name}, age:{person.age}, height:{person.height}, width:{person.width}")

# 创建一个新的Person对象并尝试设置无效的属性值  
invalid_person = Person("Charlie", -5, 300, 600) 
  
# 输出这个对象属性
print(f"name:{invalid_person.name}, age:{invalid_person.age}, height:{invalid_person.height}, width:{invalid_person.width}")

 这里可以看到终端输出的信息中,Charlie的年龄和身高体重存在明显问题,是无效属性值,而且也展示了未进行封装的坏处:

  1. 数据完整性受损:没有对数据进行合法性检查,无效或不合理的数据可以被接受并存储在对象中。

  2. 代码可维护性降低:如果后续需要添加额外的逻辑来处理属性,需要找到并修改所有直接修改属性的代码,而不是只修改一个setter方法。

  3. 安全性问题:对象的内部状态可以被外部代码随意修改,可能导致对象处于不一致或不稳定的状态。

  4. 封装性丧失:封装是面向对象编程的四大基本原则之一,它允许我们隐藏对象的内部实现细节,只通过明确定义的接口与外界交互。未封装的类违反了这一原则。

name:Alice, age:25, height:140, width:100
name:Bob, age:30, height:160, width:200
name:Charlie, age:-5, height:300, width:600

这里新建一个用于绘制年龄、身高、体重条形图的Python文件,继承上述代码中的Person类,并创建实例进行图形绘制

import matplotlib.pyplot as plt  
from Encapsulation import Person   
  
class StatisticsPerson(Person):  
    instances = []  # 类变量,用于存储实例  
  
    def __init__(self, name, age, height, width):  
        super().__init__(name, age, height, width)  
        self.instances.append(self)  # 将新创建的实例添加到instances列表中  
  
    # 使用静态方法统计所有人的年龄、身高和宽度,并绘制条状图  
    @staticmethod  
    def plot_statistics():  
        ages = [person.get_age() for person in StatisticsPerson.instances]  
        heights = [person.get_height() for person in StatisticsPerson.instances]  
        widths = [person.get_width() for person in StatisticsPerson.instances]  
  
        x = range(len(StatisticsPerson.instances))  
  
        plt.figure(figsize=(10, 6))  
        plt.bar(x, ages, label='Age', width=0.25)  
        plt.bar([i + 0.25 for i in x], heights, label='Height', width=0.25)  
        plt.bar([i + 0.5 for i in x], widths, label='Width', width=0.25)  
  
        plt.xlabel('Name')  
        plt.ylabel('Values')  
        plt.title('Comparison of Age, Height, and Width')  
        plt.xticks([i + 0.25 for i in x], [person.get_name() for person in StatisticsPerson.instances], rotation=45)  
        plt.legend() 
        plt.savefig("GGboy.png") 
        plt.show()  
  
# 创建StatisticsPerson对象  
person1 = StatisticsPerson("Alice", 25, 140, 100)  
person2 = StatisticsPerson("Bob", 30, 160, 200)  
person3 = StatisticsPerson("Charlie", 40, 175, 150)  
  
# 绘制并保存统计图  
StatisticsPerson.plot_statistics()

生成的图片:

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何保证缓存与数据库的双写一致性?

如何保证缓存与数据库的双写一致性&#xff1f; 概述同步策略更新缓存还是删除缓存&#xff1a;先操作数据库还是缓存&#xff1a;案例一、先删除缓存&#xff0c;在更新数据库案例二 先操作数据库&#xff0c;再删除缓存 延时双删策略&#xff08;不推荐&#xff09;使用分布式…

Java拆装箱及128陷阱

有以下一段代码&#xff1a; Integer a 123; Integer b 123; int c 123; int d 123; System.out.println(c d); System.out.println(a b); System.out.println(a c); 这段代码运行的结果是什么呢&#xff1f; c d 一定为True。 由于Java中存在自动拆装箱&#xff0…

刷到一个问题还请道友们解疑

问题如上&#xff0c;题目挺简单的&#xff0c;就是插入后排序的思路&#xff0c;我的代码如下&#xff1a; #include <bits/stdc.h>using namespace std; int f(int x,int y){return x < y;//其实要这个没有用&#xff0c;默认是就是从小到大排序 }int main(){int n…

【MySQL】详谈约束

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习计网、mysql和算法 ✈️专栏&#xff1a;MySQL学习 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…

PostgreSQL中控制文件的解析与恢复

最近遇到有人问起PG中控制文件的一些使用问题,总结了一下。 1、PG控制文件简介 1.1、存储的位置 它的路径位于: 相关信息,可以用命令pg_controldata得到: [10:41:27-postgres@centos2:/var/lib/pgsql/14/data/global]$ pg_controldata -D $PGDATA pg_control version …

git提交和回退

目录 一. git 提交二. git commit 后准备回退&#xff0c;尚未 git push三. git add 添加多余文件 撤销操作四. 更改 Git commit 的默认编辑器五. 撤销某个commit的变更六. 回退到之前的commit状态总结&#xff1a; 一. git 提交 git pull # 更新代码 git status # 查看代码状…

【保姆级讲解如何Stable Diffusion本地部署】

&#x1f308;个人主页:程序员不想敲代码啊&#x1f308; &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f3c6; &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提…

rancher2.6部署

rancher2.6部署 1、准备环境镜像 2、部署3、密码获取密码设置新密码 4、设置语言5、导入已有集群 1、准备 环境 docker-ce-20.10.23-3.el8.x86_64.rpm以及依赖rpm kubernetes&#xff1a;v1.23.17 镜像 &#xff08;rancher和k8s有个版本对应关系&#xff0c;rancher2.5就不…

OSCP靶场--GLPI

OSCP靶场–GLPI 考点(CVE-2022-35914 php执行函数绕过ssh端口转发jetty xml RCE) 1.nmap扫描(ssh端口转发) ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.194.242 -sV -sC --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-26 22:22 EDT Nmap…

第一个JDBC程序

一、JDBC的概念&#xff1a; JDBC 是 Java DataBase Connectivity (Java 数据连接)技术的简称&#xff0c;是一种可用于执行 SQL 语句的 Java API。它由一些 java 语言编写的类和接口组成&#xff1b;程序员通过使用 jdbc 可以方便地将 SQL 语句传送给几乎任何一种数据库。 二…

C++ :STL中vector扩容机制

vector是STL提供的动态数组&#xff0c;它会在内部空间不够用时动态的调整自身的大小&#xff0c;调整过程中会有大量的数据拷贝&#xff0c;为了减少数据拷贝的次数vector会在调整空间的时候尽量多申请一些空间&#xff0c;这些预留出的空间可以很大程度上减少拷贝的发生。 在…

Shadow Tactics

本题链接&#xff1a; 题目&#xff1a; 样例&#xff1a; 输入 1 1 3 3 U 2 2 2 输出 YES 思路&#xff1a; 根据题意&#xff0c;隼人的坐标是不会动的&#xff0c;并且士兵只能直线来回行动。 所以这里我们需要分成三种情况。 1、隼人坐标在士兵走动路线之间&#xff0c;…

linux如何查看编译器支持的C++版本(支持C++11、支持C++14、支持C++17、支持C++20)(编译时不指定g++版本,默认使用老版本编译)

参考:https://blog.csdn.net/Dontla/article/details/129016157 C各个版本 C11 C11是一个重要的C标准版本&#xff0c;于2011年发布。C11带来了许多重要的改进&#xff0c;包括&#xff1a; 智能指针&#xff1a;引入了shared_ptr和unique_ptr等智能指针&#xff0c;用于更好地…

http认证

1.Digest认证 各字段含义&#xff1a; Nonce 服务器直接返回的数据 H1MD5(user”:”realmpassword) H2MD5(method”:”url) method为请求类型、url不包括域名 Nc 指当前的第几次请求&#xff0c;使用8位16进制显示 Cnonce 8位随机字符串 ResponseMD5(H1”:”nonce”:”…

【C++语言】冲突-C语言:命名冲突(输入输出、缺省参数、引用、内联函数)

文章目录 前言正文2. C的输入与输出&#xff1a;3.缺省参数3.1 缺省参数的概念&#xff1a;3.2 缺省参数的分类&#xff1a;全缺省参数&#xff1a;半缺省参数&#xff1a; 4.函数重载4.1 函数重载的概念&#xff1a; 5.引用5.1 引用的基本概念&#xff1a;5.2 引用的特性&…

系统工程学思想

系统工程学思想 大项目或复杂问题的实施和解决&#xff0c;需要按照系统工程学理论进行&#xff0c;以系统的方法完整、全面的分析&#xff0c;而不是零星的处理问题&#xff0c;沿着逻辑推理的路径&#xff0c;去解决哪些原本靠直觉判断处理的问题。 系统分析过程逻辑结构分为…

A Review on Influence Dissemination in Social Networks

Abstract 影响力传播研究是社交网络信息传播的关键问题。由于影响力分析在营销、广告、个性化推荐、舆情监测等方面的现实意义&#xff0c;研究人员从不同角度研究了该问题并提出了解决方案。在本文中&#xff0c;我们回顾了社交网络中的影响力传播&#xff0c;并得出结论&…

淘宝APP详情数据抓取技术揭秘:用Python实现自动化数据获取(附代码实例)

获取淘宝APP详情数据接口通常涉及到网络爬虫技术&#xff0c;因为淘宝作为一个大型电商平台&#xff0c;其数据并不直接对外公开提供API接口供第三方开发者使用。然而&#xff0c;通过模拟浏览器行为或使用淘宝开放平台提供的API&#xff08;如果有的话&#xff09;&#xff0c…

借助剪映软件生成原创视频(真人人声,免VIP)

civilpy&#xff1a;借助各大模型的优点生成原创视频&#xff08;真人人声&#xff09;Plus0 赞同 0 评论文章​编辑 是的&#xff0c;剪映也出了声音克隆了&#xff0c;只需要十几秒的录音就可以克隆自己的声音&#xff0c;虽然微瑕&#xff0c;但是对于不习惯机器音的很多创…

【面试】Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法?

Elasticsearch 在部署时&#xff0c;对 Linux 的设置有哪些优化方法&#xff1f; Elasticsearch是一个分布式搜索和分析引擎&#xff0c;它在Linux环境下的性能和稳定性可以通过一些优化方法进行提升。以下是一些针对Linux环境下Elasticsearch部署的优化方法&#xff1a; 1. 内…