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 相关文章推荐
Python3非对称加密算法RSA实例详解
Dec 06 Python
对python3中, print横向输出的方法详解
Jan 28 Python
python之mock模块基本使用方法详解
Jun 27 Python
PowerBI和Python关于数据分析的对比
Jul 11 Python
TensorFlow车牌识别完整版代码(含车牌数据集)
Aug 05 Python
Python SQLAlchemy入门教程(基本用法)
Nov 11 Python
PyTorch 对应点相乘、矩阵相乘实例
Dec 27 Python
python GUI库图形界面开发之PyQt5布局控件QHBoxLayout详细使用方法与实例
Mar 06 Python
python网络编程:socketserver的基本使用方法实例分析
Apr 09 Python
Restful_framework视图组件代码实例解析
Nov 17 Python
python3中布局背景颜色代码分析
Dec 01 Python
用Python监控你的朋友都在浏览哪些网站?
May 27 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 生成唯一id的几种解决方法
2013/03/08 PHP
非常好用的Zend Framework分页类
2014/06/25 PHP
php CI框架插入一条或多条sql记录示例
2014/07/29 PHP
php实现常见图片格式的水印和缩略图制作(面向对象)
2016/06/15 PHP
php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法
2016/10/12 PHP
CI框架(CodeIgniter)实现的导入、导出数据操作示例
2018/05/24 PHP
javascript让setInteval里的函数参数中的this指向特定的对象
2010/01/31 Javascript
一个不错的js html页面倒计时可精确到秒
2014/10/22 Javascript
js文本框走动跑马灯效果代码分享
2015/08/25 Javascript
Google 地图API资料整理及详细介绍
2016/08/06 Javascript
js定时器实例分享
2016/12/20 Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
2017/01/11 Javascript
Vue2.0 vue-source jsonp 跨域请求
2017/08/04 Javascript
微信小程序中使用Promise进行异步流程处理的实例详解
2017/08/17 Javascript
react-native组件中NavigatorIOS和ListView结合使用的方法
2017/09/30 Javascript
基于canvasJS在PHP中制作动态图表
2020/05/30 Javascript
详解vue实现坐标拾取器功能示例
2020/11/18 Vue.js
Python使用smtplib模块发送电子邮件的流程详解
2016/06/27 Python
python 自动重连wifi windows的方法
2018/12/18 Python
python使用thrift教程的方法示例
2019/03/21 Python
在PyCharm中控制台输出日志分层级分颜色显示的方法
2019/07/11 Python
Python绘制二维曲线的日常应用详解
2019/12/04 Python
python爬虫如何解决图片验证码
2021/02/14 Python
英国航空官网:British Airways
2016/09/11 全球购物
台湾家适得:Homeget
2019/02/11 全球购物
下列程序在32位linux或unix中的结果是什么
2014/03/25 面试题
学校后勤人员职责
2013/12/27 职场文书
婚前保证书
2014/04/29 职场文书
2014年党员承诺书范文
2014/05/20 职场文书
英语教师自荐信
2014/05/26 职场文书
会议简讯范文
2015/07/20 职场文书
会计入职心得体会
2016/01/22 职场文书
撤回我也能看到!教你用Python制作微信防撤回脚本
2021/06/11 Python
python 字典和列表嵌套用法详解
2021/06/29 Python
Java9新特性对HTTP2协议支持与非阻塞HTTP API
2022/03/16 Java/Android
mysql如何查询连续记录
2022/05/11 MySQL