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实现class对象转换成json/字典的方法
Mar 11 Python
python模仿网页版微信发送消息功能
Feb 24 Python
numpy.transpose对三维数组的转置方法
Apr 17 Python
Python查找两个有序列表中位数的方法【基于归并算法】
Apr 20 Python
python验证码识别教程之利用滴水算法分割图片
Jun 05 Python
Python多线程原理与用法实例剖析
Jan 22 Python
Python基础学习之类与实例基本用法与注意事项详解
Jun 17 Python
PowerBI和Python关于数据分析的对比
Jul 11 Python
解决Python logging模块无法正常输出日志的问题
Feb 21 Python
Python实现自动访问网页的例子
Feb 21 Python
Matplotlib中rcParams使用方法
Jan 05 Python
OpenCV-Python直方图均衡化实现图像去雾
Jun 07 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程序员编程注意事项
2008/04/10 PHP
php的大小写敏感问题整理
2011/12/29 PHP
php之Memcache学习笔记
2013/06/17 PHP
php中 $$str 中 &quot;$$&quot; 的详解
2015/07/06 PHP
php中Redis的应用--消息传递
2017/03/28 PHP
PHP大文件分块上传功能实例详解
2019/07/22 PHP
JavaScript 学习初步 入门教程
2010/03/25 Javascript
自己写的Javascript计算时间差函数
2013/10/28 Javascript
JavaScript简单实现鼠标拖动选择功能
2014/03/06 Javascript
php基于redis处理session的方法
2016/03/14 Javascript
全面解析Bootstrap表单样式的使用
2016/09/09 Javascript
jQuery实现文字自动横移
2017/01/08 Javascript
JavaScript中双符号的运算详解
2017/03/12 Javascript
VueJs使用Amaze ui调整列表和内容页面
2017/11/30 Javascript
vue awesome swiper异步加载数据出现的bug问题
2018/07/03 Javascript
详解vue服务端渲染浏览器端缓存(keep-alive)
2018/10/12 Javascript
详解vue 动态加载并注册组件且通过 render动态创建该组件
2019/05/30 Javascript
JavaScript实现HSL拾色器
2020/05/21 Javascript
JS实现数据动态渲染的竖向步骤条
2020/06/24 Javascript
python2.x实现人民币转大写人民币
2018/06/20 Python
Django框架用户注销功能实现方法分析
2019/05/28 Python
python实现ftp文件传输功能
2020/03/20 Python
Keras 数据增强ImageDataGenerator多输入多输出实例
2020/07/03 Python
在django中实现choices字段获取对应字段值
2020/07/12 Python
sqlalchemy实现时间列自动更新教程
2020/09/02 Python
html5贪吃蛇游戏使用63行代码完美实现
2013/06/25 HTML / CSS
canvas压缩图片以及卡片制作的方法示例
2018/12/04 HTML / CSS
澳大利亚礼品篮网站:Macarthur Baskets
2019/10/14 全球购物
项目合作计划书
2014/01/09 职场文书
签约仪式策划方案
2014/06/02 职场文书
群众路线教育实践活动剖析材料
2014/09/30 职场文书
医院领导班子查摆问题对照检查材料思想汇报
2014/10/08 职场文书
一年级数学上册复习计划
2015/01/17 职场文书
安全生产培训心得体会
2016/01/18 职场文书
SpringBoot读取Resource下文件的4种方法
2021/07/02 Java/Android
Nginx配置根据url参数重定向
2022/04/11 Servers