Python基础-数据封装
来源:互联网 发布:为什么知乎登录不了 编辑:程序博客网 时间:2024/06/06 01:04
数据封装
面向对象编程的一个重要特点就是数据封装。在上面的Student类中,每个实例就拥有各自的name和score这些数据。
这样一来,我们从外部看Student类,就只需要知道,创建实例需要给出name和score,而如何打印,都是在Student类的内部定义的,这些数据和逻辑被“封装”起来了,调用很容易,但却不用知道内部实现的细节,这就是封装。
同时在内部也是现实自己不同的业务逻辑。
访问限制
再次看这个类。
class Student(object): def __init__(self, name, score): self.name = name self.score =score def print_info(self): print('Student : %s , score: %s' % (self.name, self.score))tom = Student('Tom', 90)tom.print_info()tom.score = 70tom.print_info()#打印结果Student : Tom , score: 90Student : Tom , score: 70
由此看出在外部代码还是可以自由的修改每一个实例
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改:
class Student(object): def __init__(self, name, score): self.__name = name self.__score =score def print_info(self): print('Student : %s , score: %s' % (self.__name, self.__score))tom = Student('Tom', 90)tom.print_info()print(tom.__score)tom.print_info()#打印结果AttributeError: 'Student' object has no attribute '__score'
这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
但是如果需要获取name或者score怎么办呢?
可以给Student类增加get_name和get_score这样的方法:
def get_name(self): return self.__name def get_score(self): return self.__score
如果外部需要修改属性提供set方法即可。
def set_name(self, name): self.__name = name def set_score(self, score): if 0 <= score <= 100: self.__score =score else: raise ValueError('bad score')tom.set_score(90)tom.print_info()tom.set_score(120)tom.print_info()#打印结果Student : Tom , score: 90ValueError: bad score
需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:
print(tom._Student__name)#打印结果Tom
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。
总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。
最后有一个特别要注意的。
tom = Student('Tom', 90)print(tom.get_name())tom.__name = 'New Tom'print(tom.__name)#这里看似是设置__name变量其实并没有!
但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。
print(tom.get_name())#打印还是Tom
- Python基础-数据封装
- Python数据分析基础
- Python核心基础:之三:封装
- Struts2数据封装、拦截器、标签基础
- python使用json格式进行数据封装
- python使用json格式进行数据封装
- python suds 获取webService封装的数据
- python 数据挖掘基础 入门
- Python 数据分析-pandas 基础
- Python基础学习----数据存储
- Python基础- pickle 保存数据
- python 数据分析 numpy基础
- 【Python】Python数据分析基础技术03
- python数据挖掘01--python基础
- Python面向对象1:基础介绍+封装特征
- 封装基础
- 编程基础-面向对象-数据抽象(封装)
- javascript基础之九(JavaScript数据封装)
- POJ 2020 MisLED 笔记
- bzoj2834: 回家的路
- Spring Boot学习一
- string和stringstream用法总结
- C# 反射性能
- Python基础-数据封装
- 欢迎使用CSDN-markdown编辑器
- DialogFragment 使用记录
- MySql行转列、group_concat使用
- Spring Boot: 开发web 应用
- MyBatis优化——创建工具类
- css3做一个滚动条
- PHP中变量函数和回调函数的定义和简单举例
- 15. 3Sum