谈谈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访问纯真IP数据库的代码
May 19 Python
Python读写Redis数据库操作示例
Mar 18 Python
使用Pyrex来扩展和加速Python程序的教程
Apr 13 Python
windows 10 设定计划任务自动执行 python 脚本的方法
Sep 11 Python
解决pycharm启动后总是不停的updating indices...indexing的问题
Nov 27 Python
Pandas实现DataFrame按行求百分数(比例数)
Dec 27 Python
python中wheel的用法整理
Jun 15 Python
sklearn的predict_proba使用说明
Jun 28 Python
Python pip install之SSL异常处理操作
Sep 03 Python
scrapy redis配置文件setting参数详解
Nov 18 Python
Ubuntu16安装Python3.9的实现步骤
Dec 15 Python
Python 中的单分派泛函数你真的了解吗
Jun 22 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中反射的应用
2013/06/18 PHP
php更新mysql后获取改变行数的方法
2014/12/25 PHP
MySql数据库查询结果用表格输出PHP代码示例
2015/03/20 PHP
RGB颜色值转HTML十六进制(HEX)代码的JS函数
2009/04/25 Javascript
jquery ready(fn)事件使用介绍
2013/08/21 Javascript
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
JavaScript中Function详解
2015/02/27 Javascript
jQuery实现图片预加载效果
2015/11/27 Javascript
不定义JQuery插件 不要说会JQuery
2016/03/07 Javascript
基于jQuery ligerUI实现分页样式
2016/09/18 Javascript
echarts鼠标覆盖高亮显示节点及关系名称详解
2018/03/17 Javascript
jQuery实现表单动态添加数据并提交的方法
2018/07/19 jQuery
微信小程序自定义select下拉选项框组件的实现代码
2018/08/28 Javascript
vue 本地环境跨域请求proxyTable的方法
2018/09/19 Javascript
AngularJS 多指令Scope问题的解决
2018/10/25 Javascript
js实现AI五子棋人机大战
2020/05/28 Javascript
python模拟登录百度代码分享(获取百度贴吧等级)
2013/12/27 Python
解读Python编程中的命名空间与作用域
2015/10/16 Python
使用Python和Prometheus跟踪天气的使用方法
2019/05/06 Python
pybind11在Windows下的使用教程
2019/07/04 Python
查看端口并杀进程python脚本代码
2019/12/17 Python
python小项目之五子棋游戏
2019/12/26 Python
通过python实现windows桌面截图代码实例
2020/01/17 Python
Python使用Matlab命令过程解析
2020/06/04 Python
HTML5中视频音频的使用详解
2017/07/07 HTML / CSS
简单叙述一下MYSQL的优化
2016/05/09 面试题
光电信息专业应届生求职信
2013/10/07 职场文书
中层干部岗位职责
2013/12/18 职场文书
保护环境建议书100字
2014/05/13 职场文书
丽江古城导游词
2015/02/03 职场文书
研究生论文答辩开场白
2015/05/27 职场文书
2016应届毕业生实习心得体会
2015/10/09 职场文书
廉洁自律心得体会2016
2016/01/13 职场文书
2016年中学植树节活动总结
2016/03/16 职场文书
Docker部署Mysql8的实现步骤
2022/07/07 Servers