Python3之类和实例访问限制
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。
但是,从前面的Student类定义来看,外部代码还是可以自由地修改一个实例的name,score属性
>>> bart.score
59
>>> bart.score=99
>>> bart.score
99
如果要让内部属性不被外部访问,可以把属性的名称前面加上两个下划线__,在python中,实例的变量名如果以__开头,就变成了私有变量(private),只有内部可以访问,外部不能访问
>>> 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))
...
>>> bart=Student('Zhangsan',59)
>>> 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 __init__(self,name,score):
self.__name=name
self.__score=score
def print_score(self):
print('%s:%s' %(self.__name,self.__score))
def get_name(self):
return self.__name
def get_score(self):
return self.__score
通过bart.get_name()即可返回对应name
如果又要允许外部代码修改score怎么办?可以再给Student类增加set_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))
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self,score):
self.__score=score
set_score除了self还包含一个参数score修改方法为
bart.set_score(99)
原先直接通过bart.score=99也可以直接修改,为什么要定义一个方法大费周折?因为在方法中,可以对参数进行检查,避免传入无效的参数
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))
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')
如果传递了无效的成绩会报错
Traceback (most recent call last):
File "Student.py", line 28, in <module>
bart.set_score(101)
File "Student.py", line 15, in set_score
raise ValueError('bad score')
ValueError: bad score
注意,在python中,变量名类似__xxx___,也就是以双下划线开头并且以双下划线结尾的是特殊变量,特殊变量是可以直接访问的,不是private变量,所以不能用__name__,__score__这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:
>>> bart._Student__name
'Zhangsan'
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。
注意下面这种错误写法
>>> bart=Student('Zhangsan',59)
>>> bart.get_name()
'Zhangsan'
>>> bart.__name='Lisi'
>>> bart.__name
'Lisi'
表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。不信试试:还是原来的Zhangsan
>>> bart.get_name()
'Zhangsan'
练习:
class Student(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
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:
raise ValueError('bad gender性别为male或者female')
bart=Student('Zhangsan','male')
print(bart.get_gender())
bart.set_gender('femalde')
print(bart.get_gender())
如果传递的性别参数不是male或者female则报错
Traceback (most recent call last):
File "Student2.py", line 14, in <module>
bart.set_gender('femalde')
File "Student2.py", line 11, in set_gender
raise ValueError('bad gender性别为male或者female')
ValueError: bad gender性别为male或者female
Python3之类和实例访问限制的更多相关文章
- SQL ser 跨实例访问数据库
SqlServer如何跨实例访问数据库 Exec sp_droplinkedsrvlogin LinkName,NullExec sp_dropserver LinkName go EXEC sp_a ...
- static成员是可以被其所在class创建的实例访问!!!
<span style="font-family: Arial, Helvetica, sans-serif; ">关于静态方法以及静态变量的使用就不详细的说了,我就这 ...
- Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的
转:http://www.cnblogs.com/2gua/ Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的: 1)静态方法无需传入self参数,类成员方法 ...
- 通过FEDERATED存储引擎跨实例访问数据
通过FEDERATED存储引擎同步两实例间的表数据需求情景:实例1中A库中的三个视图是实例2中的B库所依赖的,B需要A库中三个视图的实时数据.方案:通过FEDERATED来完成跨势力的查询FEDERA ...
- Python3 的urllib实例
在Python3中合并了 urllib 和 urllib2, 统一命名为 urllib 了,我觉得这样更加合理了.让我们可以像读取本地文件一样读取WEB上的数据.封装了一个类,供以后方便使用吧!并附带 ...
- Python学习 Day 7 面向对象 类和实例 访问限制
面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程 ...
- Python3面向对象编程实例
/*认真研究完这个实例,理解python面向对象编程的方法*/class Person: """人员信息""" # 姓名(共有属性) nam ...
- python3类和实例
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可 ...
- Python3之类和实例
面向对象的重要概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如学生类Student,而实例是根据类创建出来的一个个具体的对象,每个对象都拥有相同的方法,单各自的数据可能 ...
随机推荐
- <c:set> 标签
<c:set> 标签 JSP 标准标签库 <c:set>标签用于设置变量值和对象属性. <c:set>标签就是<jsp:setProperty>行为标签 ...
- 自定义的JSP标签
JSP标签 JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签. 除了这 ...
- sql server join ,inner join ,left join ,right join 的使用
测试数据脚本 CREATE TABLE Atable ( S# INT, Sname nvarchar(32), Sage INT, Sfrom nvarchar(8) ) insert into A ...
- MongoDB 查看存储引擎
需要登录到具体的主/从节点查询,mongos查询不到 db.serverStatus() 其中有这个 "storageEngine" : { "name" : ...
- 【零基础】使用Tensorflow实现神经网络
一.序言 前面已经逐步从单神经元慢慢“爬”到了神经网络并把常见的优化都逐个解析了,再往前走就是一些实际应用问题,所以在开始实际应用之前还得把“框架”翻出来,因为后面要做的工作需要我们将精力集中在业务而 ...
- rpm包和deb分别是什么?
一.RMP 是 LINUX 下的一种软件的可执行程序,你只要安装它就可以了.这种软件安装包通常是一个RPM包(Redhat Linux Packet Manager,就是Redhat的包管理器),后缀 ...
- php手记之02-tp5请求参数读取三种方式
01-[推荐方式] 当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息.在Thinkphp5.1中,获取请求对象数据,是由think\Request类负责,在很多场合下并不需 ...
- python3.6+pycharm+robotframework 环境搭建
参考文档:https://www.cnblogs.com/chenyuebai/p/8359577.html, https://www.cnblogs.com/jiyanjiao-702521/p/9 ...
- 调用微信公众平台扫一扫示例及解决接口报错 { "errMsg": "config:invalid signature" }
一.解决报错问题 单从报错信息 invalid signature 就可以看出是 签名signature 有问题, 查了很多资料,终于知道了问题点, 后台让我直接调接口是不对的,签名是根据请求接口的页 ...
- ES6展开运算符数组合并,函数传参
定义: .展开运算符允许一个表达式在某处展开. 使用场景 1.展开函数在多个参数的地方使用 .意指用于函数传参 2.多个元素的地方使用,意指用于数组字面量 3.多个边框的地方使用,意指用于解构赋值 函 ...