python学习之路(24)
访问限制
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。
但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性:
>>> class Student(object):
def __init__(self,name,score):
self.name =name
self.score = score
>>> bart =Student('lixiao',12)
>>> bart.score
12
>>> bart.score=13
>>> bart.score
13
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改:
>>> class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def print11(self):
print('%s:%s'%(self.__name,self.__score))
改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name和实例变量.__score了:
>>> bart =Student('da',12)
>>> bart.__name
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
bart.__name
AttributeError: 'Student' object has no attribute '__name'
>>>
这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
但是如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法:
class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def print11(self):
print('%s:%s'%(self.__name,self.__score))
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 = 99也可以修改啊,为什么要定义一个方法大费周折?因为在方法中,
可以对参数做检查,避免传入无效的参数
class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def print11(self):
print('%s:%s'%(self.__name,self.__score))
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self,score):
if 0<=score<=100:
self.__score = score
else:
raise ValueError('bad score')
raise ValueError('bad score') 这个函数是异常处理的意思
需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量
>>> bart._Student__name
'da'
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。
总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。
最后注意下面的这种错误写法:
>>> bart._Student__name
'da'
>>> bart=Student('dada',12)
>>> bart.get_name()
'dada'
>>> bart.__name='new name'
>>> bart.__name
'new name'
表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。不信试试:
>>> bart.get_name()
'dada'
练习
请把下面的Student对象的gender字段对外隐藏起来,用get_gender()和set_gender()代替,并检查参数有效性:
class Student(object):
def __init__(self, name, gender):
self.__name = name
self.__gender = gender
def set_gender(self,gender):
self.__gender =gender
def get_gender(self):
return self.__gender if K.get_gender()!='male':
prnit('')
else:
K.set_gender('female')
if K.get_gender()!='female':
print('')
else:
print('') 0
0x02
class Student(object):
def __init__(self, name, gender):
self.name = name
self.__gender = gender
def get_gender(self):
return self.__gender
def set_gender(self, gender):
if gender in {'male', 'female'}:
self.__gender = gender
else:
raise ValueError('bad gender')
0x03
class Student(object):
def __init__(self, name, gender):
self.name = name
self.__gender = gender def get_gender(self):
return self.__gender def set_gender(self,gender): if gender == 'male' or gender == 'female':
self.__gender = gender
else:
print('bad gender!')
python学习之路(24)的更多相关文章
- Python学习之路【第一篇】-Python简介和基础入门
1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是 ...
- python学习之路-day2-pyth基础2
一. 模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...
- Python学习之路-Day2-Python基础3
Python学习之路第三天 学习内容: 1.文件操作 2.字符转编码操作 3.函数介绍 4.递归 5.函数式编程 1.文件操作 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个 ...
- Python学习之路-Day2-Python基础2
Python学习之路第二天 学习内容: 1.模块初识 2.pyc是什么 3.python数据类型 4.数据运算 5.bytes/str之别 6.列表 7.元组 8.字典 9.字符串常用操作 1.模块初 ...
- Python学习之路-Day1-Python基础
学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...
- python学习之路网络编程篇(第四篇)
python学习之路网络编程篇(第四篇) 内容待补充
- python 学习之路开始了
python 学习之路开始了.....记录点点滴滴....
- python学习之路,2018.8.9
python学习之路,2018.8.9, 学习是一个长期坚持的过程,加油吧,少年!
- Python学习之路——pycharm的第一个项目
Python学习之路——pycharm的第一个项目 简介: 上文中已经介绍如何安装Pycharm已经环境变量的配置.现在软件已经安装成功,现在就开始动手做第一个Python项目.第一个“Hello W ...
- python学习之路------你想要的都在这里了
python学习之路------你想要的都在这里了 (根据自己的学习进度后期不断更新哟!!!) 一.python基础 1.python基础--python基本知识.七大数据类型等 2.python基础 ...
随机推荐
- Android引用多媒体
res目录下,创建raw目录(Android会自动识别这个目录),如果自己创建的目录,可能无效底下的mp3格式,mp4格式的文件名必须小写. 引用方式: mediaPlayer = MediaPlay ...
- Codeforces 1220B. Multiplication Table
传送门 冷静分析容易发现,我们只要能确定一个数的值,所有值也就可以确定了 确定一个数的值很容易,$a_ia_j=M_{i,j},a_ia_k=M_{i,k},a_ja_k=M_{j,k}$ 然后就可以 ...
- scala学习笔记(1)
scala ------------------------- java语言脚本化 1.安装scala-2.12.1.msi 2.进入到scala的命令行 3.Tab键会有补全的功能 1.scala程 ...
- id - 显示真实和有效的 UID 和 GID
总览 (SYNOPSIS) id [OPTION]... [USERNAME] 描述 (DESCRIPTION) 显示 USERNAME 或者 当前 用户 的 信息. -a 忽略, 同 其它 版本 兼 ...
- 利用cmd运行java程序
在运行以下程序时,要确保正确配置java的环境变量!!! 此处仅仅使用“记事本”来写java程序!!! 1. 新建一个记事本文件,命名为HelloWorld.java 这里需要注意的是,要确保关闭了隐 ...
- Eureka实现高可用及为Eureka设置登录账号和密码
本文通过两个eureka相互注册实现注册中心的高可用,同时为注册中心配置认证登录. 需要用到的maven配置 <dependency> <groupId>org.springf ...
- 带gcd大数模板
int ten[4] = {1,10,100,1000}; typedef struct BigNumber { int d[1200]; BigNumber(string s) { int i, j ...
- Codeforces 919 行+列前缀和 树上记忆化搜索(树形DP)
A B C #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) ...
- source insight支持查看makefile、kconfig以及.s代码方法
在用sourceinsight查看linux内核源码的时候,大家会发现不能查看源码中的makefile和kconfig代码,即不能搜索到makefile和kconfig文件.这是因为source in ...
- 微信小程序评价页面
<!--服务评价--> <view class="service"> <!--评分--> <view class='score'> ...