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,而实例是根据类创建出来的一个个具体的对象,每个对象都拥有相同的方法,单各自的数据可能 ...
随机推荐
- 关于七牛云存储配置服务器CNAME的问题
以前的图片什么的都存放在七牛云(免费的那款)上,七牛相比OSS就是只能创建bucket但不能创建文件夹,这个令人很烦.最近七牛发公告说存储文件的测试域名30天后不能使用了,那我那些存储的图片的所有外链 ...
- pygame游戏图像绘制及精灵用法
1精灵文件 plane_sprites.py import pygame class GameSprite(pygame.sprite.Sprite): """飞机大战游 ...
- The 2019 China Collegiate Programming Contest Harbin Site K. Keeping Rabbits
链接: https://codeforces.com/gym/102394/problem/K 题意: DreamGrid is the keeper of n rabbits. Initially, ...
- Java知识点汇总-1
目录 1 native方法 2 泛型 3 hashcode 4 JDK主要的包 5 被final修饰的类特点 6 空串与null串 7 判断字符串是否相等 1 native方法 JDK源代码由C++. ...
- 在mysql中用int类型存储IP
SELECT INET_ATON( '127.0.0.1' ); SELECT INET_NTOA();
- 使用 ServerSocket 建立聊天服务器-2
1. 从serverListener中可以看出,每一个客户端创建新的请求之后,都会把它分配给一个独立的chatsocket ,但是每一个ChatSocket都是相互独立的,他们之间并不能沟通,所以要新 ...
- 贴两个mysql优化的配置文件
MySQL5.7以上my.cnf配置文件配置 低配置服务器配置 [client] #客户端设置 port = 3306 socket = /data/mysql/data/mysql.sock def ...
- Python基础之给函数增加元信息
1. 参数注解 当写好一个函数以后,想为这个函数的参数添加一些额外的信息,这样的话,其他的使用者就可以清楚的知道这个函数应该怎么使用,这个时候可以使用函数参数注解. 函数参数注解能提示程序员应该怎样正 ...
- mysql插入数据自动生成主键uuid
DemoMapper.java //注意方法的返回值必须是void; void add(Demo demo); ============================================ ...
- Linux 安装软件报错 Sub-process /usr/bin/dpkg returned an error code (1)
Linux 通过 apt-get 安装软件时报错,换一个软件安装也一样. Errors were encountered while processing: blueman E: Sub-proces ...