谈谈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之Import 模块
Oct 13 Python
Python使用 Beanstalkd 做异步任务处理的方法
Apr 24 Python
Windows 64位下python3安装nltk模块
Sep 19 Python
Python实现查找最小的k个数示例【两种解法】
Jan 08 Python
如何使用django的MTV开发模式返回一个网页
Jul 22 Python
python爬虫 模拟登录人人网过程解析
Jul 31 Python
Python爬虫requests库多种用法实例
May 28 Python
Python openpyxl模块实现excel读写操作
Jun 30 Python
Python判断远程服务器上Excel文件是否被人打开的方法
Jul 13 Python
python实现图片,视频人脸识别(opencv版)
Nov 18 Python
Pandas中两个dataframe的交集和差集的示例代码
Dec 13 Python
使用Pytorch实现two-head(多输出)模型的操作
May 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
3.从实例开始
2006/10/09 PHP
PHPCMS2008广告模板SQL注入漏洞修复
2016/10/11 PHP
PHP中功能强大却很少使用的函数实例小结
2016/11/10 PHP
Lumen timezone 时区设置方法(慢了8个小时)
2018/01/20 PHP
WordPress免插件实现面包屑导航的示例代码
2020/08/20 PHP
jquery animate 动画效果使用说明
2009/11/04 Javascript
模仿JQuery sortable效果 代码有错但值得看看
2009/11/05 Javascript
JavaScript版DateAdd和DateDiff函数代码
2012/03/01 Javascript
jQuery设置div一直在页面顶部显示的方法
2013/10/24 Javascript
JavaScript 事件入门知识
2015/04/13 Javascript
JS实现下拉菜单赋值到文本框的方法
2015/08/18 Javascript
javascript和jquery实现用户登录验证
2016/05/04 Javascript
jquery实现的回旋滚动效果完整实例【附demo源码下载】
2016/09/20 Javascript
很棒的vue弹窗组件
2017/05/24 Javascript
webpack打包并将文件加载到指定的位置方法
2018/02/22 Javascript
详解javascript中的变量提升和函数提升
2018/05/24 Javascript
手把手教你vue-cli单页到多页应用的方法
2018/05/31 Javascript
JS遍历JSON数组及获取JSON数组长度操作示例【测试可用】
2018/12/12 Javascript
js时间戳转yyyy-MM-dd HH-mm-ss工具类详解
2019/04/30 Javascript
详解vue中移动端自适应方案
2019/05/05 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
2019/06/18 Javascript
JavaScript对象原型链原理详解
2020/02/05 Javascript
实例分析javascript中的异步
2020/06/02 Javascript
[52:29]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第三局
2016/03/03 DOTA
[56:41]iG vs Winstrike 2018国际邀请赛小组赛BO2 第二场
2018/08/17 DOTA
Python实现读取txt文件并画三维图简单代码示例
2017/12/09 Python
Django使用中间键实现csrf认证详解
2019/07/22 Python
python之生成多层json结构的实现
2020/02/27 Python
Python通过fnmatch模块实现文件名匹配
2020/09/30 Python
Marc Jacobs彩妆官网:Marc Jacobs Beauty
2017/07/03 全球购物
美国领先的水果篮送货公司和新鲜水果供应商:The Fruit Company
2018/02/13 全球购物
办公室文秘自我评价
2013/09/21 职场文书
爱心捐书活动总结
2014/07/05 职场文书
委托书格式
2014/08/01 职场文书
2016年毕业实习心得体会范文
2015/10/09 职场文书
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏