python 面向对象(二)--访问限制
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。
但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性:
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))
instance = Student('Andy', 60) # 类的实例
print(instance.name)
print(instance.score)
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在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))
instance = Student('Andy', 60) # 类的实例
print(instance.name)
会提示:
AttributeError: 'Student' object has no attribute 'name'
改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name和实例变量.__score了,这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
但是如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法:
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def print_score(self):
print('%s: %s' % (self.__name, self.__score))
instance = Student('Andy', 60) # 类的实例
print(instance.get_name())
但倘若又要允许外部代码修改score怎么办?可以再给Student类增加set_score方法:
class Student(object):
... def set_score(self, score):
self.__score = score
你也许会问,原先那种直接通过instance.score = 60也可以修改啊,为什么要定义一个方法大费周折?因为在方法中,可以对参数做检查,避免传入无效的参
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变量:
print(instance._Student__name) 结果:Andy
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。
总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。
最后注意下面的这种错误写法:
instance = Student('Andy', 60) # 类的实例
print(instance.get_name())
instance.__name='new Name'
print(instance.__name)
result:
Andy
new Name
[Finished in 0.1s]
表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。
python 面向对象(二)--访问限制的更多相关文章
- python面向对象(二)——类成员
Python面向对象 类成员 1.字段 普通字段 属于对象 静态字段 属于类 2.方法 普通方法 触发者是对象 括号里至少一个参数 se ...
- Python 面向对象编程——访问限制
<无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...
- python面向对象二
1.1类的静态属性,类方法,类的静态方法 1.1.1静态属性(@property) 在类中: python内置的@property装饰器就是负责把一个方法(函数)变成属性来调用. class Stud ...
- python 面向对象二 类和实例
一.类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法, ...
- python 面向对象三 访问权限 下划线 双下划线
一.双下划线 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问. ...
- Python 面向对象(二) 特殊方法
一些Python特殊方法的汇总 __bases__ 类的基类,返回元祖__base__ 类的基类,也叫父类__call__ '类名()',类名加括号调用时执行的语句__class__ 对象或类 ...
- python 面向对象(二)成员
##################################总结########################### 类的成员: 变量: 实例变量 对象.属性=xxx 类变量 ...
- python面向对象(二)
属性查找 类有两种属性:数据属性和函数属性 1. 类的数据属性是所有对象共享的 2. 类的函数属性是绑定给对象用的 class BeijingStudent: school='Beijing' ...
- Python 面向对象二(转载)
来源:www.cnblogs.com/wupeiqi/p/4766801.html 三.类成员的修饰符 类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式: 1.公有成员, ...
随机推荐
- var在IE中的问题
一个朋友问了一个js问题, 一段看不出有任何问题的代码, 在ie下报错:”object doesn’t support this property or method”. function foo(o ...
- Spring Boot 实现ErrorController接口处理404、500等错误页面
在项目中我们遇到404找不到的错误.或者500服务器错误都需要配置相应的页面给用户一个友好的提示,而在Spring Boot中我们需要如何设置. 我们需要实现ErrorController接口,重写h ...
- SpringBoot初始教程之Servlet、Filter、Listener配置详解
1.介绍 通过之前的文章来看,SpringBoot涵盖了很多配置,但是往往一些配置是采用原生的Servlet进行的,但是在SpringBoot中不需要配置web.xml的 因为有可能打包之后是一个ja ...
- win10电脑的USB接口插上U盘以后不能使用?
今天刚遇到的问题 解决方法如下: 右击“我的电脑”选“属性”,打开“设备管理器”,双击“通用串行总线控制器”,双击任意一个,打开属性对话框,切换到“电源管理”选项卡,去除“允许计算机关闭这个设备以节约 ...
- python3 FTP简单实现文件下载(含中文乱码问题)
from ftplib import FTP def ftp_down(HOST,romatepath,filename,localpath): user=***** password=***** f ...
- Lights Out Game
Lights Out Game 在线的游戏:http://www.neok12.com/games/lights-out/lights-out.htm 瞎试一阵子未成之后,终于找到了标准答案:http ...
- [转]FireFox与IE 下js兼容触发click事件的代码
本文转自:http://www.jb51.net/article/16549.htm FireFox与IE 下js兼容触发click事件 ,对于需要兼容这两者的朋友,就需要参考下下面的代码了<a ...
- 【Linux】Debian vim没有颜色的解决办法
vim /etc/vim/vimrc #查找到syntax on 启用,去掉前面的“ (引号). 保存ok 转载地址:http://www.th7.cn/system/lin/201404/525 ...
- PhpStorm快捷键设置,个性化设置,多项目共存,更改样式主题字体
自定义常用快捷键 按照路径:File -> Settings -> Appearance & Behavior -> Keymap -> Copy 一份 Eclipse ...
- IT方面书籍下载整理
最近翻看Redis相关的中文书籍时,发现了很多错误,包括翻译错误及理论错误,因此想搜集一些相关的外文书籍看看.以下几个链接,内容大同小异,均可免费下载相关的英文书籍PDF版,内容涵盖了IT的方方面面. ...