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脚本来获取Google搜索结果的示例
May 04 Python
Python中处理字符串之isalpha()方法的使用
May 18 Python
Python中的rjust()方法使用详解
May 19 Python
Python列表list解析操作示例【整数操作、字符操作、矩阵操作】
Jul 25 Python
Python实现的爬取网易动态评论操作示例
Jun 06 Python
Django添加favicon.ico图标的示例代码
Aug 07 Python
python调用matplotlib模块绘制柱状图
Oct 18 Python
关于sys.stdout和print的区别详解
Dec 05 Python
通过python检测字符串的字母
Feb 18 Python
python之MSE、MAE、RMSE的使用
Feb 24 Python
Python如何转换字符串大小写
Jun 04 Python
python 删除系统中的文件(按时间,大小,扩展名)
Nov 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
php中smarty实现多模版网站的方法
2015/06/11 PHP
摘自织梦CMS中的图片处理类
2015/08/08 PHP
php中目录操作opendir()、readdir()及scandir()用法示例
2019/06/08 PHP
jQuery中文入门指南,翻译加实例,jQuery的起点教程
2007/01/13 Javascript
用户注册常用javascript代码
2009/08/29 Javascript
鼠标拖动实现DIV排序示例代码
2013/10/14 Javascript
javascript:json数据的页面绑定示例代码
2014/01/26 Javascript
AngularJS入门知识之MVW类框架的编程思想探讨
2014/12/08 Javascript
简易的投票系统以及js刷票思路和方法
2015/04/07 Javascript
JS验证IP,子网掩码,网关和MAC的方法
2015/07/02 Javascript
JavaScript 正则表达式中global模式的特性
2016/02/25 Javascript
vue组件实践之可搜索下拉框功能
2018/11/25 Javascript
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
Promise扫盲贴
2019/06/24 Javascript
JS数据类型STRING使用实例解析
2019/12/18 Javascript
vue+vant实现商品列表批量倒计时功能
2020/01/13 Javascript
Js视频播放器插件Video.js使用方法详解
2020/02/04 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
2020/09/04 Javascript
详解vue-cli项目在IE浏览器打开报错解决方法
2020/12/10 Vue.js
pytyon 带有重复的全排列
2013/08/13 Python
Python中random模块用法实例分析
2015/05/19 Python
浅谈python 四种数值类型(int,long,float,complex)
2016/06/08 Python
简单谈谈Python中的元祖(Tuple)和字典(Dict)
2017/04/21 Python
python中不能连接超时的问题及解决方法
2018/06/10 Python
对pandas的算术运算和数据对齐实例详解
2018/12/22 Python
浅谈python之高阶函数和匿名函数
2019/03/21 Python
Python递归调用实现数字累加的代码
2020/02/25 Python
CSS3实战第一波 让我们尽情的圆角吧
2010/08/27 HTML / CSS
乐高奥地利官方商店:LEGO Shop AT
2019/07/16 全球购物
雷蛇美国官网:Razer
2020/04/03 全球购物
写好自荐信的要点
2013/11/06 职场文书
护士毕业自我鉴定
2014/02/07 职场文书
授权委托书范本
2014/04/03 职场文书
环保倡议书300字
2014/05/15 职场文书
员工评语范文
2014/12/31 职场文书
客户付款通知书
2015/04/23 职场文书