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正则表达式介绍
Aug 06 Python
python使用wmi模块获取windows下的系统信息 监控系统
Oct 27 Python
Python处理文本文件中控制字符的方法
Feb 07 Python
对Django中的权限和分组管理实例讲解
Aug 16 Python
pyinstaller打包程序exe踩过的坑
Nov 19 Python
django ajax发送post请求的两种方法
Jan 05 Python
Python range与enumerate函数区别解析
Feb 28 Python
python读取文件指定行内容实例讲解
Mar 02 Python
解决Jupyter Notebook开始菜单栏Anaconda下消失的问题
Apr 13 Python
Django框架获取form表单数据方式总结
Apr 22 Python
python异步Web框架sanic的实现
Apr 27 Python
Python基础知识之变量的详解
Apr 14 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新手上路(七)
2006/10/09 PHP
PHP使用PHPexcel导入导出数据的方法
2015/11/14 PHP
[原创]保存的js无法执行的解决办法
2007/02/25 Javascript
Jquery知识点三 jquery表单对象操作
2011/01/17 Javascript
IE6,IE7,IE8下使用Javascript记录光标选中范围(已补全)
2011/08/28 Javascript
js动态生成指定行数的表格
2013/07/11 Javascript
NodeJS制作爬虫全过程
2014/12/22 NodeJs
AngularJS中实现显示或隐藏动画效果的方式总结
2015/12/31 Javascript
深入剖析JavaScript:Object类型
2016/05/10 Javascript
webix+springmvc session超时跳转登录页面
2016/10/30 Javascript
Bootstrap的popover(弹出框)2秒后定时消失的实现代码
2017/02/27 Javascript
JS实现简单抖动效果
2017/06/01 Javascript
vue2.0 循环遍历加载不同图片的方法
2018/03/06 Javascript
Vue中 v-if/v-show/插值表达式导致闪现的原因及解决办法
2018/10/12 Javascript
Vue的H5页面唤起支付宝支付功能
2019/04/18 Javascript
layui递归实现动态左侧菜单
2019/07/26 Javascript
JS实现可视化音频效果的实例代码
2020/01/16 Javascript
Layer UI表格列日期格式化及取消自动填充日期的实现方法
2020/05/10 Javascript
对vue生命周期的深入理解
2020/12/03 Vue.js
python中enumerate的用法实例解析
2014/08/18 Python
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
Python代码实现删除一个list里面重复元素的方法
2019/04/02 Python
python如何实现从视频中提取每秒图片
2020/10/22 Python
PyTorch中常用的激活函数的方法示例
2019/08/20 Python
Python @property使用方法解析
2019/09/17 Python
python操作cfg配置文件方式
2019/12/22 Python
python @propert装饰器使用方法原理解析
2019/12/25 Python
用python发送微信消息
2020/12/21 Python
Godiva巧克力英国官网:比利时歌帝梵巧克力
2018/08/28 全球购物
控制工程专业个人求职信
2013/09/25 职场文书
高职教师先进事迹材料
2014/08/24 职场文书
2014党员学习习主席讲话思想汇报
2014/09/15 职场文书
2014年财政工作总结
2014/12/10 职场文书
法律意见书范文
2015/05/20 职场文书
2015年行政人事工作总结
2015/05/21 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书