python中属于私有属性的是_Python中的实例属性和私有属性

相关知识点

实例属性

实例属性和类属性的区别在于实例属性定义在类的__init__()魔法方法中,而类属性定义在类下:

1 classC:2 b = 1 #类属性

3

4 def __init__(self):5 self.x = None #实例属性

对于类属性这里不做说明,主要描述实例属性,

实例属性生效的方式要先知道的一点是Python中实例化一个类,类的魔法方法__init__()会被自动调用,

所以对于类对象C来说,是不存在实例属性的,在C类对象被实例化的时候,实例属性x才会被创建:

1 classC:2 b = 1

3

4 def __init__(self):5 self.x =None6

7 print(C.b)8 print(C.x)

上述代码中行7print会被执行,因为C.b是类属性,类属性可以被使用,

但是行7的print会报错AttributeError: type object 'C' has no attribute 'x' ,就是因为C类对象没有x属性,因为__init__()只有在类对象被实例化的时候,才会被执行,

当C类对象被实例化,访问实例对象的x,就不会报错,这就是实例属性(只有实例才能访问):

1 classC:2 b = 1

3

4 def __init__(self):5 self.x =None6

7

8 a = C() #实例化C

9 print(a.x) #访问a实例的x

私有属性

有些时候我们定义一个类,并且构造了实例属性,并且在内部方法中使用了这个属性,通常不希望这个属性会被外部(类方法外)更改,否则就会出现一些不可预料的问题,例如:

1 classC:2

3 def __init__(self):4 self.doc = '这个例子是我在2020_06_11写的'

5

6 defprintf(self):7 print(f'{self.doc}')8

9 a = C() #把C实例化,命名为a

10 a.doc = '我想给a实例增加一个doc属性' #本来的想法是给a实例增加一个doc属性,但是却不知道C实例在内部也定义了doc实例属性,并且在类方法中需要用到这个属性

11 a.printf()

这段代码的输出:我想给a实例增加一个doc属性

上述的例子中只是改了一个doc,在实际编码过程中,这个属性很可能是一个关键数据,类方法强依赖于这个属性,如果未经校验就让外部直接对这个属性进行修改,就会造成不可预估的后果,很可能需要花很长时间来定位问题。

综上所述在一些场景下,我们需要把类属性定义为私有属性,这样我们在外部就无法对实例的私有属性做修改,而在类内部,却依然可以对私有属性做修改和处理,

下面我们举一个数字类的加法例子:

1 classNum:2

3 def __init__(self):4 self.__x = 1

5 self.__y = 2

6

7 defprintf(self):8 print(f'{self.__x}加{self.__y}的和是:{self.__x+self.__y}')9

10 a = Num() #把C实例化,命名为a

11 a.printf()

这段代码输出是:1加2的和是:3

这个例子中我们就把实例属性x和y前面加上了双下划线__,告诉Python解释器这个是私有属性,不能被更改,

这个时候如果我们企图在类的外部修改私有属性,实际上实例方法printf中调用的实例对象__x,__y就不会受到影响:

1 classNum:2

3 def __init__(self):4 self.__x = 1

5 self.__y = 2

6

7 defprintf(self):8 print(f'{self.__x}加{self.__y}的和是:{self.__x+self.__y}')9

10 a = Num() #把C实例化,命名为a

11 a.__x = 5

12 a.__y = 5

13 a.printf()

这里的返回仍然是:1加2的和是:3

因为我们把x和y定义成了私有属性,就这么简单

总结

Python中实例实例属性在类被实例化的时候才会被创建;

以双下划线__开头的实例属性被称为私有属性,私有属性不会被类外部修改。

拓展知识

实际上在Python中并没有绝对的私有和共有属性,

我们使用双下划线的方式来定义一个私有实例属性,也仅仅是提醒上层:这是一个私有变量,请不要擅自修改,否则可能出现不可预知的错误!

所以为什么我们可以通过这种方式来限制上层让上层的修改无效呢?

我们可以用实例对象的魔法方法__dir__()来查看这个实例拥有的属性:

1 classNum:2

3 def __init__(self):4 self.__num = 1

5

6

7 a = Num() #把C实例化,命名为a

8 print(a.__dir__())

输出:

['_Num__num', '__module__', '__init__', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']

其他的可以不看,a实例下会有一个'_Num__num' 属性,这个属性就是我们在初始化函数__init__()中定义的__num,

到这里就已经很清楚了,Python解释器,把双下划线开头的__num认为是私有属性,把私有属性重命名成了 _类名 + 私有属性名,

所以我们在上层可以对实例对象的__num重新赋值,但是并不会影响类内部使用的self.__num,这只是因为调用的self.__num和重新定义的a.__name并不是同一个属性,

我们可以通过这种方式来验证我们的想法:

1 classNum:2

3 def __init__(self):4 self.__num = 1

5

6 defprintf(self):7 print(self.__num)8

9 a = Num() #把C实例化,命名为a

10 print('下面调用类方法printf,输出类中的__name')11 a.printf()12 print('接下来在外部修改__name的值,再输出看看外部调用的__name的值')13 a.__num = 3

14 print(a.__num)15 print('再看看我们这个实例的属性和方法')16 print(a.__dir__())

这里的输出:

下面调用类方法printf,输出类中的__name1

接下来在外部修改__name的值,再输出看看外部调用的__name的值3

再看看我们这个实例的属性和方法['_Num__num', '__num', '__module__', '__init__', 'printf', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']

现在实锤了,类中的self.__name实际上是_Num__num,我们外部定义的a.__name实际上就是__name

所以如果我们就是想要修改私有属性,我们就可以这样做:

1 classNum:2

3 def __init__(self):4 self.__num = 1

5

6 defprintf(self):7 print(self.__num)8

9 a = Num() #把C实例化,命名为a

10 print('下面调用类方法printf,输出类中的__name')11 a.printf()12 print('接下来在外部修改_Num__num的值')13 a._Num__num = 3

14 print('下面直接在外部访问私有属性')15 print(a._Num__num)16 print('下面调用类方法printf,输出类中的__name')17 a.printf()

输出:

下面调用类方法printf,输出类中的__name

1

接下来在外部修改_Num__num的值

下面直接在外部访问私有属性

3

下面调用类方法printf,输出类中的__name

3

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

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

相关文章

osgi cxf_所有OSGi套件的通用CXF请求拦截器

osgi cxf几个月以来,我一直在研究Apache CXF,Karaf和Felix,我发现所有这些捆绑技术都非常有趣。 在处理一些用例时,我陷入一种情况,即我只需要一个Interceptor即可在发送到Karaf应用程序下部署的任何捆绑包的每个HTTP请…

听说,高手都用记事本写C语言代码?

坊间传闻高手都喜欢用记事本写代码,那么问题来了,我们以C语言为例,如何用记事本编译运行呢?其实,最简单的方式就是安装GCC编译器,在记事本编写C语言程序,然后再在命令行用GCC编译运行。下面&…

精简指令和复杂指令计算机,CPU精简指令集和复杂指令集的区别

经常看到计算机课程上介绍PowerPC是采用精简指令集的CPU,酷睿CPU是复杂指令集。那么到底精简指令集和复杂指令集有什么区别呢?以下内容摘自百度百科:在计算机指令系统的优化发展过程中,出现过两个截然不同的优化方向:C…

均值差异大但是t检验不显著_T检验原理及介绍

T检验原理及应用介绍一、T检验的应用场景:应用场景:可以用于研究工艺更改前后对于产品质量是否有显著提高;研究不同的热处理温度对于产品性能,晶粒度等是否有明显效果;研究不同的设备或人员对于产品质量的影响是否有差…

javafx ui_调用以验证JavaFX UI的响应能力

javafx ui最近,吉姆韦弗(Jim Weaver)在他的Surface Pro上安装了我的小图片索引应用“ picmodo”作为演示,图形用户界面(GUI)变成了垃圾。 显然,Windows Tablet上JavaFX的基本字体大小很高&…

python中mean的用法_Python statistics mean()用法及代码示例

先决条件:统计函数简介 在数据分析和统计方面,Python是一种非常流行的语言。幸运的是,Python3提供了statistics模块,它具有非常有用的功能,例如mean(),median(),mode()等等 mean()函数可用于计算…

C语言多文件编程基本格式

1、背景:用一个丢骰子的简单案例熟悉了C语言多文件编程该咋写2、格式(1)主函数文件main.c//文件头part1:所有要使用的函数#include ;#include ;#include ;//文件头part2:放所有函数原型的文件#inlucde "main.h"//文件头part3&#…

微软project服务器搭建,Project Professional 版本(Project Server 2010 设置)

Project Professional 版本利用“Project Professional 版本”,您可以指定将能够连接到 Project Server 2010 环境的 Project Professional 客户端的版本(内部版本号)。可通过此设置确保与服务器的 Project Professional 客户端连接都处于所需的基本级别。例如&…

众辰nz200变频器使用说明书_ABB变频器

ABB变频器,广州丰电自动化设备有限公司是一家专业从事工业计算机、工业自动化产品、电线电缆、仪器仪表销售、安装、维修;变频控制系统、变频恒压供水系统、变频节能系统的设计及安装,提供自动化工程技术服务及成套解决方案于一体的科技企业。…

pb 执行存储过程带参数_PB级海量数据服务平台架构设计实践

基于PB级海量数据实现数据服务平台,需要从各个不同的角度去权衡,主要包括实践背景、技术选型、架构设计,我们基于这三个方面进行了架构实践,下面分别从这三个方面进行详细分析讨论:实践背景该数据服务平台架构设计之初…

4g的服务器mysql配置文件,服务器物理内存16G mysql数据库my.cnf配置及参数说明

搜索热词《服务器物理内存16G MysqL数据库my.cnf配置及参数说明》要点:本文介绍了服务器物理内存16G MysqL数据库my.cnf配置及参数说明,希望对您有用。如果有疑问,可以联系我们。导读:服务器物理内存16G MysqL数据库my.cnf配置及参…

C语言*运算符和运算符

取址运算符&用来取得其操作数的地址。如果操作数 x 的类型为 T,则表达式 &x 的类型是 T 类型指针(指向 T 的指针)。取址运算符的操作数必须是在内存中可寻址到的地址。换句话说,该运算符只能用于函数或对象(例…

mockito 单元测试_使用FizzBu​​zz和Mockito进行单元测试

mockito 单元测试我有时使用FizzBu​​zz向新手演示单元测试的基础。 尽管FizzBu​​zz确实是一个简单的问题,但它也可以用于演示更高级的单元测试技术,例如模拟 。 FizzBu​​zz Kata: “ 编写一个程序,打印一个从1到100的数字…

css 竖行进度图_前端学习--汇集了大量 CSS 的使用和学习的示例代码

CSS-Inspiration这里可以让你寻找到使用或者是学习 CSS 的灵感,以分类的形式,展示不同 CSS 属性或者不同的课题使用 CSS 来解决的各种方法。目前已有上百种的CSS 实现示例,代码可以拿 来即用LayoutCSS实现瀑布流布局(display: flex)CSS实现瀑…

socket io 不使用redis_Redis这么快,线程模型竟然是单线程

Redis的线程模型记住一句话:单进程单线程,IO多路复用。单线程还这么快?是的,你没有看错,Redis是单线程处理的。这是因为Redis的设计者认为Redis是基于内存的操作,瓶颈在内存或者网络带宽而不是CPU。这样&am…

java 统一处理时区_Java时区处理初学者指南

java 统一处理时区基本时间观念 大多数Web应用程序必须支持不同的时区,而正确处理时区绝非易事。 更糟糕的是,您必须确保各种编程语言(例如,前端JavaScript,中间件中的Java和作为数据存储库的MongoDB)之间的…

服务器系统装内存条,hp服务器怎么安装内存条 hp服务器内存推荐【图文】

服务器虚拟化增加了在每台惠普服务器上运行工作负载的数量,但是越来越多的计算需求则要求IT人员配备更好的HP服务器配件。因此需要对于HP服务器内存市场行情有一定的了解,而选择合适的HP服务器内存却是一件非常难的事情,今天就跟小编一起来看…

7个C语言小程序让你快速入门程序世界

1、题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去掉不满足条件的排列。程序源代码:#include#…

去重 属性_面试中常问的List去重问题,你都答对了吗?

面试中经常被问到的list如何去重,用来考察你对list数据结构,以及相关方法的掌握,体现你的java基础学的是否牢固。我们大家都知道,set集合的特点就是没有重复的元素。如果集合中的数据类型是基本数据类型,可以直接将lis…

python paramiko模块下载_Python自动化运维实战:使用Python管理网络设备

现在,我们已经知道如何在不同的操作系统中使用和安装Python以及如何使用EVE-NG搭建网络拓扑。在本章中,我们将学习如何使用目前常用的网络自动化库自动完成各种网络任务。Python可以在不同的网络层上与网络设备进行交互。首先,Python可以通过…