谈谈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字典多条件排序方法实例
Jun 30 Python
python 实现红包随机生成算法的简单实例
Jan 04 Python
Python生成随机数组的方法小结
Apr 15 Python
python中requests小技巧
May 10 Python
PyTorch学习笔记之回归实战
May 28 Python
python引入不同文件夹下的自定义模块方法
Oct 27 Python
在Python中定义一个常量的方法
Nov 10 Python
Python使用combinations实现排列组合的方法
Nov 13 Python
python读写配置文件操作示例
Jul 03 Python
opencv 图像滤波(均值,方框,高斯,中值)
Jul 08 Python
详细分析Python collections工具库
Jul 16 Python
python 实用工具状态机transitions
Nov 21 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读取文件内容到数组的方法
2015/03/16 PHP
PHP页面跳转实现延时跳转的方法
2016/12/10 PHP
PHP实现验证码校验功能
2017/11/16 PHP
php设计模式之抽象工厂模式分析【星际争霸游戏案例】
2020/01/23 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
php判断IP地址是否在多个IP段内
2020/08/18 PHP
Jquery 设置标题的自动翻转
2009/10/03 Javascript
JQuery中的$.getJSON 使用说明
2011/03/10 Javascript
javascript 寻找错误方法整理
2014/06/15 Javascript
使用AOP改善javascript代码
2015/05/01 Javascript
简单理解vue中实例属性vm.$els
2016/12/01 Javascript
纯js实现悬浮按钮组件
2016/12/17 Javascript
JS 实现缓存算法的示例(FIFO/LRU)
2018/03/20 Javascript
vue-cli配置环境变量的方法
2018/07/09 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
2019/08/01 Javascript
微信小程序自定义弹出模态框禁止底部滚动功能
2020/03/09 Javascript
[01:02:03]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS VG
2014/05/26 DOTA
整理Python 常用string函数(收藏)
2016/05/30 Python
Python实现的tcp端口检测操作示例
2018/07/24 Python
攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)
2018/10/11 Python
Python常见数据类型转换操作示例
2019/05/08 Python
Python直接赋值、浅拷贝与深度拷贝实例分析
2019/06/18 Python
基于python 取余问题(%)详解
2020/06/03 Python
美国最大网上鞋店:Zappos
2016/07/25 全球购物
bonprix匈牙利:女士、男士和儿童服装
2019/07/19 全球购物
Prototype是怎么扩展DOM的
2014/10/01 面试题
请说出以下代码输出什么
2013/08/30 面试题
工商管理毕业生推荐信
2013/12/24 职场文书
乡镇办公室工作决心书
2014/03/11 职场文书
奥巴马连任演讲稿
2014/05/15 职场文书
教师四风问题整改措施
2014/09/25 职场文书
湖南省党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
离职报告范文
2014/11/04 职场文书
2014年大学学生会工作总结
2014/12/02 职场文书
毕业生党员个人总结
2015/02/14 职场文书
《窃读记》教学反思
2016/02/18 职场文书