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调用新浪微博API项目实践
Jul 28 Python
Python将多个excel表格合并为一个表格
Feb 22 Python
Java编程迭代地删除文件夹及其下的所有文件实例
Feb 10 Python
python 删除指定时间间隔之前的文件实例
Apr 24 Python
使用python中的in ,not in来检查元素是不是在列表中的方法
Jul 06 Python
详解django2中关于时间处理策略
Mar 06 Python
Python常见数字运算操作实例小结
Mar 22 Python
django admin 根据choice字段选择的不同来显示不同的页面方式
May 13 Python
python中pandas库中DataFrame对行和列的操作使用方法示例
Jun 14 Python
python中format函数如何使用
Jun 22 Python
Django Model层F,Q对象和聚合函数原理解析
Nov 12 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
Dec 01 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 简单数组排序实现代码
2009/08/05 PHP
php学习之变量的使用
2011/05/29 PHP
PHP遍历某个目录下的所有文件和子文件夹的实现代码
2013/06/28 PHP
smarty模板局部缓存方法使用示例
2014/06/17 PHP
Destoon旺旺无法正常显示,点击提示“会员名不存在”的解决办法
2014/06/21 PHP
PHP导入导出Excel代码
2015/07/07 PHP
JQuery AJAX实现目录浏览与编辑的代码
2008/10/21 Javascript
使用iframe window的scroll方法控制iframe页面滚动
2014/03/05 Javascript
js如何打印object对象
2015/10/16 Javascript
原生JS实现拖拽图片效果
2020/08/27 Javascript
js获取鼠标点击的对象,点击另一个按钮删除该对象的实现代码
2016/05/13 Javascript
利用css+原生js制作简单的钟表
2020/04/07 Javascript
JS短信验证码倒计时功能的实现(没有验证码,只有倒计时)
2016/10/27 Javascript
详解react服务端渲染(同构)的方法
2017/09/21 Javascript
nodejs中art-template模板语法的引入及冲突解决方案
2017/11/07 NodeJs
vue 实现通过手机发送短信验证码注册功能
2018/04/19 Javascript
Vue中JS动画与Velocity.js的结合使用
2019/02/13 Javascript
详解vue更改头像功能实现
2019/04/28 Javascript
JavaScript 实现同时选取多个时间段的方法
2019/10/17 Javascript
js实现无限层级树形数据结构(创新算法)
2020/02/27 Javascript
Python闭包实现计数器的方法
2015/05/05 Python
详解Python中用于计算指数的exp()方法
2015/05/14 Python
Python引用类型和值类型的区别与使用解析
2017/10/17 Python
Python中最大最小赋值小技巧(分享)
2017/12/23 Python
详解如何在python中读写和存储matlab的数据文件(*.mat)
2018/02/24 Python
基于Python实现剪切板实时监控方法解析
2019/09/11 Python
Tensorflow训练MNIST手写数字识别模型
2020/02/13 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
HTML5 视频播放(video),JavaScript控制视频的实例代码
2018/10/08 HTML / CSS
澳大利亚电子产品购物网站:Dick Smith
2017/02/02 全球购物
什么是托管函数?托管函数有什么用?
2014/06/15 面试题
英文留学推荐信范文
2014/01/25 职场文书
幼儿园儿童节活动主持词+串词大全
2014/03/21 职场文书
实施意见格式范本
2015/06/05 职场文书
MySQL数据迁移相关总结
2021/04/29 MySQL
JavaScript执行机制详细介绍
2021/12/06 Javascript