谈谈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创建声明性迷你语言的教程
Apr 13 Python
使用Python装饰器在Django框架下去除冗余代码的教程
Apr 16 Python
python实现数独算法实例
Jun 09 Python
分析并输出Python代码依赖的库的实现代码
Aug 09 Python
如何使用七牛Python SDK写一个同步脚本及使用教程
Aug 23 Python
浅谈python函数之作用域(python3.5)
Oct 27 Python
浅谈Django自定义模板标签template_tags的用处
Dec 20 Python
Python实现定时精度可调节的定时器
Apr 15 Python
Python http接口自动化测试框架实现方法示例
Dec 06 Python
python使用numpy实现直方图反向投影示例
Jan 17 Python
Matplotlib使用Cursor实现UI定位的示例代码
Mar 12 Python
python判断是空的实例分享
Jul 06 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创建动态图像
2006/10/09 PHP
php+js实现异步图片上传实例分享
2014/06/02 PHP
php中mkdir函数用法实例分析
2014/11/15 PHP
PHP中常用的字符串格式化函数总结
2014/11/19 PHP
Zend Framework框架Smarty扩展实现方法
2016/03/22 PHP
php实现按天数、星期、月份查询的搜索框
2016/05/02 PHP
PHP封装请求类实例分析【基于Yii框架】
2019/10/17 PHP
基于jQuery UI CSS Framework开发Widget的经验
2010/08/21 Javascript
javascript中的数字与字符串相加实例分析
2011/08/14 Javascript
js 实现日期灵活格式化的小例子
2013/07/14 Javascript
JS下拉缓冲菜单示例代码
2013/08/30 Javascript
关于删除时的提示处理(确定删除吗)
2013/11/03 Javascript
JQuery实现动态表格点击按钮表格增加一行
2014/08/24 Javascript
使用JavaScript+canvas实现图片裁剪
2015/01/30 Javascript
js实现每日自动换一张图片的方法
2015/05/04 Javascript
小巧强大的jquery layer弹窗弹层插件
2015/12/06 Javascript
vue使用mint-ui实现下拉刷新和无限滚动的示例代码
2017/11/06 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
javascript标准库(js的标准内置对象)总结
2018/05/26 Javascript
element-ui组件中input等的change事件中传递自定义参数
2019/05/22 Javascript
Vue调用后端java接口的实例代码
2019/10/28 Javascript
详解微信小程序之提高应用速度小技巧
2020/01/07 Javascript
JavaScript canvas绘制渐变颜色的矩形
2020/02/18 Javascript
js根据后缀判断文件文件类型的代码
2020/05/09 Javascript
Cython 三分钟入门教程
2009/09/17 Python
Python获取远程文件大小的函数代码分享
2014/05/13 Python
Python中的模块导入和读取键盘输入的方法
2015/10/16 Python
详解python编译器和解释器的区别
2019/06/24 Python
python代理工具mitmproxy使用指南
2019/07/04 Python
Python 3.8正式发布,来尝鲜这些新特性吧
2019/10/15 Python
在Python中利用pickle保存变量的实例
2019/12/30 Python
html5的自定义data-*属性与jquery的data()方法的使用
2014/07/02 HTML / CSS
澳大利亚优质的家居用品和生活方式公司:Bed Bath N’ Table
2019/04/16 全球购物
简短的公司员工自我评价分享
2013/11/13 职场文书
爱护公物演讲稿
2014/09/09 职场文书
幼师个人总结范文
2015/02/28 职场文书