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的常见命令注入威胁
Feb 18 Python
python实现html转ubb代码(html2ubb)
Jul 03 Python
Python中标准模块importlib详解
Apr 16 Python
python的Tqdm模块的使用
Jan 10 Python
pyspark 读取csv文件创建DataFrame的两种方法
Jun 07 Python
Tensorflow 同时载入多个模型的实例讲解
Jul 27 Python
Python面向对象之类的内置attr属性示例
Dec 14 Python
Django框架设置cookies与获取cookies操作详解
May 27 Python
Python利用多线程同步锁实现多窗口订票系统(推荐)
Dec 22 Python
Python run()函数和start()函数的比较和差别介绍
May 03 Python
降低python版本的操作方法
Sep 11 Python
BeautifulSoup中find和find_all的使用详解
Dec 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中的正规表达式(二)
2006/10/09 PHP
zend framework重定向方法小结
2016/05/28 PHP
PHP 的Opcache加速的使用方法
2017/12/29 PHP
比较全的JS checkbox全选、取消全选、删除功能代码
2008/12/19 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
2013/01/23 Javascript
jQuery之日期选择器的深入解析
2013/06/19 Javascript
基于MVC3方式实现下拉列表联动(JQuery)
2013/09/02 Javascript
jquery修改属性值实例代码(设置属性值)
2014/01/06 Javascript
原生js结合html5制作简易的双色子游戏
2015/03/30 Javascript
nodejs调用cmd命令实现复制目录
2015/05/04 NodeJs
jquery if条件语句的写法
2016/05/19 Javascript
BootStrap学习系列之Bootstrap Typeahead 组件实现百度下拉效果(续)
2016/07/07 Javascript
Angular外部使用js调用Angular控制器中的函数方法或变量用法示例
2016/08/05 Javascript
js实现前端分页页码管理
2017/01/06 Javascript
nginx+vue.js实现前后端分离的示例代码
2018/02/12 Javascript
详解Node.js中的Async和Await函数
2018/02/22 Javascript
js前端面试之同步与异步问题详解
2019/04/03 Javascript
微信公众号获取用户地理位置并列出附近的门店的示例代码
2019/07/25 Javascript
es6中reduce的基本使用方法
2019/09/10 Javascript
使用webpack搭建vue环境的教程详解
2019/12/31 Javascript
[01:05:00]2018国际邀请赛 表演赛 Pain vs OpenAI
2018/08/24 DOTA
Python使用urllib2模块实现断点续传下载的方法
2015/06/17 Python
Python虚拟环境virtualenv的安装与使用详解
2017/05/28 Python
在python中以相同顺序shuffle两个list的方法
2018/12/13 Python
python selenium循环登陆网站的实现
2019/11/04 Python
Python3 shelve对象持久存储原理详解
2020/03/23 Python
Python tempfile模块生成临时文件和临时目录
2020/09/30 Python
美国网上购买眼镜:Eyeconic
2017/07/29 全球购物
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
警察思想汇报
2014/01/04 职场文书
《理想的风筝》教学反思
2014/04/11 职场文书
个人授权委托书范本
2014/09/14 职场文书
教育项目合作协议书格式
2014/10/17 职场文书
苦儿流浪记读书笔记
2015/07/01 职场文书
Python数据分析之pandas读取数据
2021/06/02 Python
Java详细解析==和equals的区别
2022/04/07 Java/Android