谈谈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爬虫入门教程之点点美女图片爬虫代码分享
Sep 02 Python
Python实现替换文件中指定内容的方法
Mar 19 Python
Python 循环语句之 while,for语句详解
Apr 23 Python
python 将数据保存为excel的xls格式(实例讲解)
May 03 Python
ubuntu17.4下为python和python3装上pip的方法
Jun 12 Python
解决安装pyqt5之后无法打开spyder的问题
Dec 13 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
Dec 26 Python
Pandas 解决dataframe的一列进行向下顺移问题
Dec 27 Python
k-means 聚类算法与Python实现代码
Jun 01 Python
Django封装交互接口代码
Jul 12 Python
Python必须了解的35个关键词
Jul 16 Python
matplotlib 多个图像共用一个colorbar的实现示例
Sep 10 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
自动跳转中英文页面
2006/10/09 PHP
php解析html类库simple_html_dom(详细介绍)
2013/07/05 PHP
php旋转图片90度的方法
2013/11/07 PHP
PHP中Memcache操作类及用法实例
2014/12/12 PHP
php实现图片转换成ASCII码的方法
2015/04/03 PHP
Yii框架实现邮箱激活的方法【数字签名】
2016/10/18 PHP
jquery数组过滤筛选方法grep()简介
2014/06/06 Javascript
AngularJS 与百度地图的结合实例
2016/10/20 Javascript
jQuery实现用户输入自动完成功能
2017/02/13 Javascript
详解Nuxt.js Vue服务端渲染摸索
2018/02/08 Javascript
JavaScript中变量、指针和引用功能与操作示例
2018/08/04 Javascript
详解vue-video-player使用心得(兼容m3u8)
2019/08/23 Javascript
三步实现ionic3点击退出app程序
2019/09/17 Javascript
vue项目出现页面空白的解决方案
2019/10/31 Javascript
9种方法优化jQuery代码详解
2020/02/04 jQuery
[42:35]2018DOTA2亚洲邀请赛3月30日 小组赛A组 VG VS OpTic
2018/03/31 DOTA
python实现多线程采集的2个代码例子
2014/07/07 Python
python中list常用操作实例详解
2015/06/03 Python
Linux上安装Python的PIL和Pillow库处理图片的实例教程
2016/06/23 Python
OPENCV去除小连通区域,去除孔洞的实例讲解
2018/06/21 Python
Python实现计算文件MD5和SHA1的方法示例
2019/06/11 Python
python实现复制大量文件功能
2019/08/31 Python
python实现网站微信登录的示例代码
2019/09/18 Python
Python Tornado批量上传图片并显示功能
2020/03/26 Python
详解查看Python解释器路径的两种方式
2020/10/15 Python
韩都衣舍天猫官方旗舰店:天猫女装销售总冠军
2017/10/10 全球购物
G-Form护具官方网站:美国运动保护装备
2019/09/04 全球购物
豪华复古化妆:Besame Cosmetics
2019/09/06 全球购物
毕业生个人求职信范例分享
2013/12/17 职场文书
数学与统计学院学生个人职业生涯规划书
2014/02/10 职场文书
工作态度检讨书
2014/02/11 职场文书
财务主管岗位职责
2014/02/28 职场文书
先进单位申报材料
2014/12/25 职场文书
特此通知格式
2015/04/27 职场文书
自愿离婚协议书范本2016
2016/03/18 职场文书
Python装饰器详细介绍
2022/03/25 Python