谈谈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 05 Python
python使用multiprocessing模块实现带回调函数的异步调用方法
Apr 18 Python
python在指定目录下查找gif文件的方法
May 04 Python
在Python中使用next()方法操作文件的教程
May 24 Python
python使用 zip 同时迭代多个序列示例
Jul 06 Python
使用OpenCV circle函数图像上画圆的示例代码
Dec 27 Python
django商品分类及商品数据建模实例详解
Jan 03 Python
python使用Geany编辑器配置方法
Feb 21 Python
Python使用itcaht库实现微信自动收发消息功能
Jul 13 Python
Django model重写save方法及update踩坑详解
Jul 27 Python
如何使用python写截屏小工具
Sep 29 Python
Pytorch 中的optimizer使用说明
Mar 03 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把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
php抽象类使用要点与注意事项分析
2015/02/09 PHP
PHP工程师VIM配置分享
2015/12/15 PHP
php 判断字符串编码是utf-8 或gb2312实例
2016/11/01 PHP
thinkPHP5实现的查询数据库并返回json数据实例
2017/10/23 PHP
在 PHP 和 Laravel 中使用 Traits的方法
2019/11/13 PHP
javascript中的变量是传值还是传址的?
2010/04/19 Javascript
ajax中get和post的说明及使用与区别
2012/12/23 Javascript
通过正则格式化url查询字符串实现代码
2012/12/28 Javascript
JQuery记住用户名和密码的具体实现
2014/04/04 Javascript
简介AngularJS中使用factory和service的方法
2015/06/17 Javascript
JS实现方向键切换输入框焦点的方法
2015/08/19 Javascript
JavaScript判断对象是否为数组
2015/12/22 Javascript
JS与Ajax Get和Post在使用上的区别实例详解
2016/06/08 Javascript
针对BootStrap中tabs控件的美化和完善(推荐)
2016/07/06 Javascript
javascript判断回文数详解及实现代码
2017/02/03 Javascript
原生js实现放大镜特效
2017/03/08 Javascript
详解nodejs中的process进程
2017/03/19 NodeJs
vue2.0 elementUI制作面包屑导航栏
2018/02/22 Javascript
Vue-路由导航菜单栏的高亮设置方法
2018/03/17 Javascript
JS实现HTML页面中动态显示当前时间完整示例
2018/07/30 Javascript
vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
2018/11/29 Javascript
json数据格式常见操作示例
2019/06/13 Javascript
vue路由教程之静态路由
2019/09/03 Javascript
[02:43]DOTA2亚洲邀请赛场馆攻略——带你走进东方体育中心
2018/03/19 DOTA
详细解析Python当中的数据类型和变量
2015/04/25 Python
python3新特性函数注释Function Annotations用法分析
2016/07/28 Python
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
Python视频编辑库MoviePy的使用
2020/04/01 Python
Python之变量类型和if判断方式
2020/05/05 Python
解决python执行较大excel文件openpyxl慢问题
2020/05/15 Python
会走路的树教学反思
2014/02/20 职场文书
2014年秋季开学寄语
2014/08/02 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
2016年共产党员个人承诺书
2016/03/24 职场文书
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
2022/04/14 Python