Python中设置变量访问权限的方法


Posted in Python onApril 27, 2015

在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。

但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性:

>>> bart = Student('Bart Simpson', 98)
>>> bart.score
98
>>> bart.score = 59
>>> bart.score
59

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改:

class Student(object):

 def __init__(self, name, score):
  self.__name = name
  self.__score = score

 def print_score(self):
  print '%s: %s' % (self.__name, self.__score)

改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name和实例变量.__score了:

>>> bart = Student('Bart Simpson', 98)
>>> bart.__name
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'

这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。

但是如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法:

class Student(object):
 ...

 def get_name(self):
  return self.__name

 def get_score(self):
  return self.__score

如果又要允许外部代码修改score怎么办?可以给Student类增加set_score方法:

class Student(object):
 ...

 def set_score(self, score):
  self.__score = score

你也许会问,原先那种直接通过bart.score = 59也可以修改啊,为什么要定义一个方法大费周折?因为在方法中,可以对参数做检查,避免传入无效的参数:

class Student(object):
 ...

 def set_score(self, score):
  if 0 <= score <= 100:
   self.__score = score
  else:
   raise ValueError('bad score')

需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。

有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:

>>> bart._Student__name
'Bart Simpson'

但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。

总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。

Python 相关文章推荐
Python 时间操作例子和时间格式化参数小结
Apr 24 Python
python Socket之客户端和服务端握手详解
Sep 18 Python
Python系统监控模块psutil功能与经典用法分析
May 24 Python
Linux上使用Python统计每天的键盘输入次数
Apr 17 Python
利用python和百度地图API实现数据地图标注的方法
May 13 Python
python 求某条线上特定x值或y值的点坐标方法
Jul 09 Python
关于Python核心框架tornado的异步协程的2种方法详解
Aug 28 Python
Numpy与Pytorch 矩阵操作方式
Dec 27 Python
15行Python代码实现免费发送手机短信推送消息功能
Feb 27 Python
使用numpy nonzero 找出非0元素
May 14 Python
python接口测试返回数据为字典取值方式
Feb 12 Python
python绘制云雨图raincloud plot
Aug 05 Python
理解Python中的类与实例
Apr 27 #Python
简述Python中的面向对象编程的概念
Apr 27 #Python
介绍Python中的__future__模块
Apr 27 #Python
在Python中使用第三方模块的教程
Apr 27 #Python
在Python中使用模块的教程
Apr 27 #Python
详细介绍Python中的偏函数
Apr 27 #Python
举例讲解Python中装饰器的用法
Apr 27 #Python
You might like
phpphp图片采集后按原路径保存图片示例
2014/02/18 PHP
PHP把数字转成人民币大写的函数分享
2014/06/30 PHP
PHP远程采集图片详细教程
2014/07/01 PHP
php实现随机显示图片方法汇总
2015/05/21 PHP
十个PHP高级应用技巧果断收藏
2015/09/25 PHP
编写PHP脚本来实现WordPress中评论分页的功能
2015/12/10 PHP
7款吸引人眼球的jQuery/CSS3特效实例分享
2013/04/25 Javascript
js文件缓存之版本管理详解
2013/07/05 Javascript
JS将秒换成时分秒实现代码
2013/09/03 Javascript
jquery ajaxSubmit 异步提交的简单实现
2014/02/28 Javascript
基于豆瓣API+Angular开发的web App
2015/01/02 Javascript
JS实现选中当前菜单后高亮显示的导航条效果
2015/10/15 Javascript
Bootstrap中表单控件状态(验证状态)
2016/08/04 Javascript
JavaScript实现图片懒加载(Lazyload)
2016/11/28 Javascript
Html5 js实现手风琴效果
2020/04/17 Javascript
Mac系统下Webstorm快捷键整理大全
2017/05/28 Javascript
详解vue-cli脚手架build目录中的dev-server.js配置文件
2017/11/24 Javascript
微信小程序实现同时上传多张图片
2020/02/03 Javascript
详解node.js创建一个web服务器(Server)的详细步骤
2021/01/15 Javascript
用Python的SimPy库简化复杂的编程模型的介绍
2015/04/13 Python
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
Python 爬虫图片简单实现
2017/06/01 Python
AI人工智能 Python实现人机对话
2017/11/13 Python
Python操作rabbitMQ的示例代码
2019/03/19 Python
Python Django框架防御CSRF攻击的方法分析
2019/10/18 Python
flask利用flask-wtf验证上传的文件的方法
2020/01/17 Python
Python新手如何进行闭包时绑定变量操作
2020/05/29 Python
python 实现IP子网计算
2021/02/18 Python
新西兰杂志订阅:isubscribe
2019/08/26 全球购物
考试作弊被抓检讨书
2014/01/10 职场文书
酒店七夕情人节活动策划方案
2014/08/24 职场文书
自习课吵闹检讨书范文
2014/09/26 职场文书
优秀学生干部事迹材料
2014/12/24 职场文书
教师节随笔
2015/08/15 职场文书
nginx location优先级的深入讲解
2021/03/31 Servers
Python闭包的定义和使用方法
2022/04/11 Python