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六大开源框架对比
Oct 19 Python
python 定义给定初值或长度的list方法
Jun 23 Python
django+echart绘制曲线图的方法示例
Nov 26 Python
Python自动化测试笔试面试题精选
Mar 12 Python
Python响应对象text属性乱码解决方案
Mar 31 Python
Python使用扩展库pywin32实现批量文档打印实例
Apr 09 Python
python IDLE添加行号显示教程
Apr 25 Python
vscode写python时的代码错误提醒和自动格式化的方法
May 07 Python
在Keras中CNN联合LSTM进行分类实例
Jun 29 Python
浅谈tensorflow 中的图片读取和裁剪方式
Jun 30 Python
Python通过len函数返回对象长度
Oct 22 Python
Python实现淘宝秒杀功能的示例代码
Jan 19 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
基于Discuz security.inc.php代码的深入分析
2013/06/03 PHP
php跨服务器访问方法小结
2015/05/12 PHP
php实现的验证码文件类实例
2015/06/18 PHP
PHP连接MYSQL数据库实例代码
2016/01/20 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
2017/09/17 PHP
PHP实现二维数组中的查找算法小结
2018/06/09 PHP
PHP+swoole+linux实现系统监控和性能优化操作示例
2019/04/15 PHP
thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
2019/07/15 PHP
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
Mootools 1.2教程 类(一)
2009/09/15 Javascript
javascript中的继承实例代码
2011/04/27 Javascript
jquery实现按Enter键触发事件示例
2013/09/10 Javascript
JavaScript实现存储HTML字符串示例
2014/04/21 Javascript
javascript中使用正则计算中文长度的例子
2014/04/29 Javascript
js函数内变量的作用域分析
2015/01/12 Javascript
EasyUI中在表单提交之前进行验证
2016/07/19 Javascript
详解angularJs中自定义directive的数据交互
2017/01/13 Javascript
深入探究AngularJs之$scope对象(作用域)
2017/07/20 Javascript
解决ie img标签内存泄漏的问题
2017/10/13 Javascript
谈谈React中的Render Props模式
2018/12/06 Javascript
vue请求数据的三种方式
2020/03/04 Javascript
Python中的ceil()方法使用教程
2015/05/14 Python
python删除列表内容
2015/08/04 Python
神经网络python源码分享
2017/12/15 Python
Python实现图片拼接的代码
2018/07/02 Python
PySide和PyQt加载ui文件的两种方法
2019/02/27 Python
PyQt5实现暗黑风格的计时器
2019/07/29 Python
Python 爬虫的原理
2020/07/30 Python
一款纯css3实现的tab选项卡的实列教程
2014/12/11 HTML / CSS
大学生活动策划方案
2014/02/10 职场文书
《骑牛比赛》教后反思
2014/04/22 职场文书
竞选学委演讲稿
2014/09/13 职场文书
一年级语文上册复习计划
2015/01/17 职场文书
学校安全管理制度
2015/08/06 职场文书
体育委员竞选稿
2015/11/21 职场文书
Go语言实现一个简单的并发聊天室的项目实战
2022/03/18 Golang