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根据文件大小打log日志
Oct 09 Python
pygame学习笔记(6):完成一个简单的游戏
Apr 15 Python
编写Python的web框架中的Model的教程
Apr 29 Python
对python 数据处理中的LabelEncoder 和 OneHotEncoder详解
Jul 11 Python
Python使用分布式锁的代码演示示例
Jul 30 Python
解决pycharm 工具栏Tool中找不到Run manager.py Task的问题
Jul 01 Python
在PyTorch中Tensor的查找和筛选例子
Aug 18 Python
Python 中使用 PyMySQL模块操作数据库的方法
Nov 10 Python
Python利用多线程同步锁实现多窗口订票系统(推荐)
Dec 22 Python
如何将PySpark导入Python的放实现(2种)
Apr 26 Python
python中如何打包用户自定义模块
Sep 23 Python
Python3+Django get/post请求实现教程详解
Feb 16 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
php实现统计邮件大小的方法
2013/08/06 PHP
PHP实现根据图片色界在不同位置加水印的方法
2015/08/08 PHP
Symfony核心类概述
2016/03/17 PHP
PHP获取redis里不存在的6位随机数应用示例【设置24小时过时】
2017/06/07 PHP
JavaScript多线程的实现方法
2007/05/08 Javascript
实现变速回到顶部的JavaScript代码
2011/05/09 Javascript
关于页面嵌入swf覆盖div层的问题的解决方法
2014/02/11 Javascript
分享使用AngularJS创建应用的5个框架
2015/12/05 Javascript
关于动态执行代码(js的Eval)实例详解
2016/08/15 Javascript
浅谈JS之tagNaem和nodeName
2016/09/13 Javascript
es6学习之解构时应该注意的点
2017/08/29 Javascript
基于bootstrop常用类总结(推荐)
2017/09/11 Javascript
bootstrap-Treeview实现级联勾选
2017/11/23 Javascript
JS实现的透明度渐变动画效果示例
2018/04/28 Javascript
Vue头像处理方案小结
2018/07/26 Javascript
玩转vue的slot内容分发
2018/09/22 Javascript
搭建基于express框架运行环境的方法步骤
2018/11/15 Javascript
vue实现Excel文件的上传与下载功能的两种方式
2019/06/28 Javascript
vue实现两个区域滚动条同步滚动
2020/12/13 Vue.js
[04:32]玩具屠夫中文语音节选
2020/08/23 DOTA
python连接mysql调用存储过程示例
2014/03/05 Python
Python实现时钟显示效果思路详解
2018/04/11 Python
python将字符串转变成dict格式的实现
2019/11/18 Python
Python中的__init__作用是什么
2020/06/09 Python
Django实现内容缓存实例方法
2020/06/30 Python
HTML5的video标签的浏览器兼容性增强方案分享
2016/05/19 HTML / CSS
音乐专业应届生教师求职信
2013/11/04 职场文书
公务员总结性个人自我评价
2013/12/05 职场文书
实习自我鉴定
2013/12/15 职场文书
如何编写优秀的食品项目创业计划书
2014/01/23 职场文书
如何写一份好的英文求职信
2014/03/19 职场文书
学校四风问题对照检查材料思想汇报
2014/09/26 职场文书
测量员岗位职责
2015/02/14 职场文书
英雄儿女观后感
2015/06/09 职场文书
行政处罚决定书
2015/06/24 职场文书
保安辞职申请书应该怎么写?
2019/07/15 职场文书