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 22 Python
python实现实时监控文件的方法
Aug 26 Python
Python中取整的几种方法小结
Jan 06 Python
详解Python中 sys.argv[]的用法简明解释
Dec 20 Python
python opencv3实现人脸识别(windows)
May 25 Python
opencv python 图像去噪的实现方法
Aug 31 Python
python实现整数的二进制循环移位
Mar 08 Python
python读写配置文件操作示例
Jul 03 Python
关于Django Models CharField 参数说明
Mar 31 Python
Keras load_model 导入错误的解决方式
Jun 09 Python
Python中的With语句的使用及原理
Jul 29 Python
教你怎么用Python生成九宫格照片
May 20 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正则过滤html标签、空格、换行符的代码(附说明)
2010/10/25 PHP
php无限分类且支持输出树状图的详细介绍
2013/06/19 PHP
深入浅出php socket编程
2015/05/13 PHP
php常用字符串长度函数strlen()与mb_strlen()用法实例分析
2019/06/25 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
JSONP 跨域访问代理API-yahooapis实现代码
2012/12/02 Javascript
一个简单的JS时间控件示例代码(JS时分秒时间控件)
2013/11/22 Javascript
Jquery uploadify图片上传插件无法上传的解决方法
2013/12/16 Javascript
css+js实现部分区域高亮可编辑遮罩层
2014/03/04 Javascript
Javascript中String的常用方法实例分析
2015/06/13 Javascript
jQuery实现hover合成事件的方法
2015/08/06 Javascript
微信小程序 Page()函数详解
2016/10/17 Javascript
基于jQuery的checkbox全选问题分析
2016/11/18 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
2017/11/02 Javascript
Vue.js实现的计算器功能完整示例
2018/07/11 Javascript
解决eclipse中没有js代码提示的问题
2018/10/10 Javascript
基于elementUI使用v-model实现经纬度输入的vue组件
2019/05/12 Javascript
Vue proxyTable配置多个接口地址,解决跨域的问题
2020/09/11 Javascript
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
2016/06/02 Python
Python进阶之递归函数的用法及其示例
2018/01/31 Python
python自动12306抢票软件实现代码
2018/02/24 Python
洛杉矶健身中心女性专用运动服饰品牌:Marika
2018/05/09 全球购物
阿迪达斯英国官方网站:adidas英国
2019/08/13 全球购物
法国滑雪假期的专家:Ski Planet
2019/11/02 全球购物
法律顾问服务方案
2014/05/15 职场文书
捐助贫困学生倡议书
2014/05/16 职场文书
机关党员四风问题个人整改措施
2014/10/26 职场文书
优秀班集体申报材料
2014/12/25 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
离婚承诺书格式范文
2015/05/04 职场文书
放牛班的春天观后感
2015/06/01 职场文书
党支部考察鉴定意见
2015/06/02 职场文书
天堂的孩子观后感
2015/06/11 职场文书
评奖评优个人先进事迹材料
2015/11/04 职场文书
2016国庆节活动宣传语
2015/11/25 职场文书
关于nginx 实现jira反向代理的问题
2021/09/25 Servers