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:为什么类中的私有属性可以在外部赋值并访问就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 群星《前途海量 电影原声专辑》[FLAC/分轨][227.78MB]
- 张信哲.1992-知道新曲与精丫巨石】【WAV+CUE】
- 王翠玲.1995-ANGEL【新艺宝】【WAV+CUE】
- 景冈山.1996-我的眼里只有你【大地唱片】【WAV+CUE】
- 群星《八戒 电影原声带》[320K/MP3][188.97MB]
- 群星《我的阿勒泰 影视原声带》[320K/MP3][139.47MB]
- 纪钧瀚《胎教古典音乐 钢琴与大提琴的沉浸时光》[320K/MP3][148.91MB]
- 刘雅丽.2001-丽花皇后·EMI精选王【EMI百代】【FLAC分轨】
- 齐秦.1994-黄金十年1981-1990CHINA.TOUR.LIVE精丫上华】【WAV+CUE】
- 群星.2008-本色·百代音乐人创作专辑【EMI百代】【WAV+CUE】
- 群星.2001-同步过冬AVCD【环球】【WAV+CUE】
- 群星.2020-同步过冬2020冀待晴空【环球】【WAV+CUE】
- 沈雁.1986-四季(2012梦田复刻版)【白云唱片】【WAV+CUE】
- 纪钧瀚《胎教古典音乐 钢琴与大提琴的沉浸时光》[FLAC/分轨][257.88MB]
- 《国语老歌 怀旧篇 3CD》[WAV/分轨][1.6GB]