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中getattr函数使用方法 getattr实现工厂模式
Jan 20 Python
你所不知道的Python奇技淫巧13招【实用】
Dec 14 Python
获取Django项目的全部url方法详解
Oct 26 Python
对python程序内存泄漏调试的记录
Jun 11 Python
Django中如何防范CSRF跨站点请求伪造攻击的实现
Apr 28 Python
python opencv实现图像边缘检测
Apr 29 Python
python爬虫 基于requests模块发起ajax的get请求实现解析
Aug 20 Python
pytorch 预训练层的使用方法
Aug 20 Python
Python3 把一个列表按指定数目分成多个列表的方式
Dec 25 Python
Python中sys模块功能与用法实例详解
Feb 26 Python
浅谈matplotlib.pyplot与axes的关系
Mar 06 Python
使用Python绘制台风轨迹图的示例代码
Sep 21 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
PHP学习之PHP表达式
2006/10/09 PHP
使用PHP的日期与时间函数技巧
2008/04/24 PHP
Windows IIS PHP 5.2 安装与配置方法
2009/06/08 PHP
Nginx服务器上安装并配置PHPMyAdmin的教程
2015/08/18 PHP
浅谈php和js中json的编码和解码
2016/10/24 PHP
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
简单实现php上传文件功能
2017/09/21 PHP
PHP仿tp实现mvc框架基本设计思路与实现方法分析
2018/05/23 PHP
js实现点小图看大图效果的思路及示例代码
2013/10/28 Javascript
javascript中typeof的使用示例
2013/12/19 Javascript
AngularJS入门教程(零):引导程序
2014/12/06 Javascript
jQuery实现视频作为全屏幕背景
2014/12/18 Javascript
jquery实现简单的全选和反选功能
2016/01/02 Javascript
自己动手制作基于jQuery的Web页面加载进度条插件
2016/06/03 Javascript
socket.io学习教程之基础介绍(一)
2017/04/29 Javascript
使用Webpack 搭建 Vue3 开发环境过程详解
2020/07/28 Javascript
[48:00]EG vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.26
2018/08/29 DOTA
编写Python脚本批量下载DesktopNexus壁纸的教程
2015/05/06 Python
利用python获取当前日期前后N天或N月日期的方法示例
2017/07/30 Python
python 连接各类主流数据库的实例代码
2018/01/30 Python
Python使用ConfigParser模块操作配置文件的方法
2018/06/29 Python
PySide和PyQt加载ui文件的两种方法
2019/02/27 Python
Python利用WMI实现ping命令的例子
2019/08/14 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
tensorflow 分类损失函数使用小记
2020/02/18 Python
Python生成六万个随机,唯一的8位数字和数字组成的随机字符串实例
2020/03/03 Python
Ted Baker英国官网:男士和女士服装及配件
2017/03/13 全球购物
Hoka One One法国官网:美国专业跑鞋品牌
2018/12/29 全球购物
澳大利亚有机化妆品网上商店:The Well Store
2020/02/20 全球购物
奠基仪式策划方案
2014/05/15 职场文书
学校四群教育实施方案
2014/06/12 职场文书
科学发展观演讲稿
2014/09/11 职场文书
大学学生会竞选稿
2015/11/19 职场文书
Redis 彻底禁用RDB持久化操作
2021/07/09 Redis
Ruby序列化和持久化存储 Marshal和Pstore介绍
2022/04/18 Ruby