谈谈Python:为什么类中的私有属性可以在外部赋值并访问


Posted in Python onMarch 05, 2020

Python:为什么类中的私有属性可以在外部赋值并访问?

问题引入

在慕课网上学习Python**类中的私有属性**的时候,看到了一个同学的提问:

将count改为__count,为什么实例变量在外部仍然可以修改__count?这里print p1.__count可以打印出100

class Person(object):
 __count = 0
 def __init__(self, name):
  Person.__count = Person.__count + 1
  self.name = name
  print Person.__count
 p1 = Person('Bob')
 p1.__count=100
 print p1.__count
 p2 = Person('Alice')

print Person.__count

问题解决:

单刀直入版:

这是因为给p1.__count赋值的操作,其实是在p1中定义了一个名为__count的变量(因为Python中的都是动态变量),而没有改变类中真正的属性。

太长但还是要看看版:

知识点清单:

1、类的“伪私有属性”
2、在类的外部动态地创建类属性

问题解决过程:

1、“伪私有属性”的概念:

python的类中通过加双下划线来设置的“私有属性”其实是“伪私有属性”,原理是python编译器将加了双下划线的“属性名”自动转换成“类名属性名”。所以我们在外部用“属性名”访问私有属性的时候,会触发AttributeError,从而实现“私有属性”的特性。但通过“类名属性名”也可以访问这些属性。

参考:http://www.pythonclub.org/python-class/private

2、编写测试代码:

以下是在该同学的代码的基础上修改的测试代码:

class Person(object):
 #设置类属性
 __count_of_class = 'original count_of_class'
 def __init__(self, name):
  self.name = name
  print('in class Person : count_of_class = ', Person.__count_of_class,'\n')

#初始化实例p1
p1 = Person('Bob')
#在实例p1上修改属性值
p1.__count_of_class='I\'m not the original count_of_class!'
print('p1\'s _Person__count_of_class = ',p1._Person__count_of_class)
print('p1\'s __count_of_class = ',p1.__count_of_class,'\n')

#在类Person上修改属性值
Person.__count_of_class = 'I\'m not the original count_of_class!'
#将这句注释取消掉,会发现真正的私有属性的值也改变了
#Person._Person__count_of_class = 'I\'m not the original count_of_class!'
print('Person\'s _Person__count_of_class = ',Person._Person__count_of_class)
print('Person\'s __count_of_class = ',Person.__count_of_class)

分别在实例p1上和类Person上进行操作,并且分别打印出“__属性名”,以及“_类名__属性名”。

输出结果如下:

in class Person : count_of_class = original count_of_class

p1's _Person__count_of_class = original count_of_class
p1's __count_of_class = I'm not the original count_of_class!

Person's _Person__count_of_class = original count_of_class
Person's __count_of_class = I'm not the original count_of_class!

**由此可见,虽然用p1.__count_of_class给它赋值了,但其实在类中真正的属性_Person__count_of_class的原始值是没有改变的。

但是如果将p1._Person__count_of_class赋值,那么类属性定义的原始值就真正地被覆盖了**

"""
取消掉
##Person._Person__count_of_class = 'I\'m not the original count_of_class!'
的注释,输出结果:
"""

in class Person : count_of_class = original count_of_class 
p1's _Person__count_of_class = original count_of_class 
p1's __count_of_class = I'm not the original count_of_class! 

#注意这一句:
Person's _Person__count_of_class = I'm not the original count_of_class! 
Person's __count_of_class = I'm not the original count_of_class!

由此,我们知道了:_count_of_class和_Person_count_of_class不是同一个东西。

最后的问题

但是呢,如果不先给p1.__count_of_class赋值,直接打印它又会触发AttributeError,这是为什么?

这是因为给p1.__count_of_class赋值的操作,其实是在p1中定义了一个名为__count_of_class的变量(因为Python中的都是动态变量)。

以下实例说明可以通过外部赋值来为类创造属性:

class Person(object):
 pass

p1=Person()
#给p1创建属性new_of_instance
p1.new_of_instance = 'I\'m new in p1!'
print(p1.new_of_instance)

#给Person类创建属性new_of_class
Person.new_of_class = 'I\'m new in Person!'

#在类中新加的属性,可以通过实例来访问
print(p1.new_of_class)


>>>输出:
I'm new in p1!
I'm new in Person!

问题解决。

以上这篇谈谈Python:为什么类中的私有属性可以在外部赋值并访问就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python高效编程技巧
Jan 07 Python
python基础练习之几个简单的游戏
Nov 10 Python
Python基于ThreadingTCPServer创建多线程代理的方法示例
Jan 11 Python
python进行两个表格对比的方法
Jun 27 Python
Python3实现的简单三级菜单功能示例
Mar 12 Python
python里运用私有属性和方法总结
Jul 08 Python
django 文件上传功能的相关实例代码(简单易懂)
Jan 22 Python
利用 Python ElementTree 生成 xml的实例
Mar 06 Python
Python文件操作基础流程解析
Mar 19 Python
Python jieba结巴分词原理及用法解析
Nov 05 Python
使用pandas读取表格数据并进行单行数据拼接的详细教程
Mar 03 Python
python数字图像处理之对比度与亮度调整示例
Jun 28 Python
python如何将两张图片生成为全景图片
Mar 05 #Python
Python 定义只读属性的实现方式
Mar 05 #Python
Pycharm中import torch报错的快速解决方法
Mar 05 #Python
Python中私有属性的定义方式
Mar 05 #Python
Python实现AI自动抠图实例解析
Mar 05 #Python
python GUI库图形界面开发之PyQt5 MDI(多文档窗口)QMidArea详细使用方法与实例
Mar 05 #Python
Python matplotlib修改默认字体的操作
Mar 05 #Python
You might like
PHP多线程之内部多线程实例分析
2015/03/09 PHP
一个简单的jQuery插件制作 学习过程及实例
2010/04/25 Javascript
一些常用的JavaScript函数(json)附详细说明
2011/05/25 Javascript
js定时器怎么写?就是在特定时间执行某段程序
2013/10/11 Javascript
JS小功能(checkbox实现全选和全取消)实例代码
2013/11/28 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
2014/02/04 Javascript
javascript for-in有序遍历json数据并探讨各个浏览器差异
2015/11/30 Javascript
微信小程序中顶部导航栏的实现代码
2017/03/30 Javascript
JS请求servlet功能示例
2017/06/01 Javascript
详解用node.js实现简单的反向代理
2017/06/26 Javascript
Sublime Text新建.vue模板并高亮(图文教程)
2017/10/26 Javascript
JS highcharts实现动态曲线代码示例
2020/10/16 Javascript
[03:17]DOTA2英雄基础教程 剧毒术士
2013/12/12 DOTA
Python科学画图代码分享
2017/11/29 Python
python3 遍历删除特定后缀名文件的方法
2018/04/23 Python
python爬取微信公众号文章
2018/08/31 Python
Python读写文件基础知识点
2019/06/10 Python
python3.7简单的爬虫实例详解
2019/07/08 Python
TensorFLow 数学运算的示例代码
2020/04/21 Python
python 实现"神经衰弱"翻牌游戏
2020/11/09 Python
CSS3控制HTML元素动画效果
2014/02/08 HTML / CSS
css3media响应式布局实例
2016/07/08 HTML / CSS
启动一个线程是用run()还是start()
2016/12/25 面试题
PyQt QMainWindow的使用示例
2021/03/24 Python
智能电子应届生求职信
2013/11/10 职场文书
高三高考决心书
2014/03/11 职场文书
机关搬迁方案
2014/05/18 职场文书
办公室文员岗位职责范本
2014/06/12 职场文书
领导班子党的群众路线教育实践活动对照检查材料
2014/09/25 职场文书
《你在为谁工作》心得体会(共8篇)
2016/01/20 职场文书
如何书写先进事迹材料?
2019/07/02 职场文书
Python标准库之typing的用法(类型标注)
2021/06/02 Python
Python基础之变量的相关知识总结
2021/06/23 Python
为什么MySQL选择Repeatable Read作为默认隔离级别
2021/07/26 MySQL
Python使用BeautifulSoup4修改网页内容
2022/05/20 Python
Oracle查看表空间使用率以及爆满解决方案详解
2022/07/23 Oracle