从小白到小黑 python学习之旅 日常总结 28(类2 封装)
类 的使用
class School: school_name = 'OLDBOY' def __init__(self, nickname, addr): self.nickname = nickname #别名 self.addr = addr #地址 self.classes = [] #班级 def related_class(self, class_obj): # self.classes.append(班级名字) # self.classes.append(class_name) self.classes.append(class_obj) def tell_class(self): # 改 # 打印的班级的名字 print(self.nickname.center(60,'=')) # 打印班级开设的课程信息 for class_obj in self.classes: class_obj.tell_course() # 一:学校 # 创建校区 造对象 school_obj1=School('老男孩魔都校区','上海') school_obj2=School('老男孩帝都校区','北京') class Class: def __init__(self, name): self.name = name self.course = None def related_course(self, course_obj): # self.course = course_name self.course = course_obj def tell_course(self): print('%s' % self.name,end=" ") self.course.tell_info() # 打印课程的详细信息 # 二:班级 # 创建班级 造对象 class_obj1 = Class('脱产14期') class_obj2 = Class('脱产15期') class_obj3 = Class('脱产29期') # 为学校开设班级 # 上海校区开了:脱产14期,上海校区开了脱产15期 school_obj1.related_class(class_obj1) school_obj1.related_class(class_obj2) # 北京校区开了:脱产29期 school_obj2.related_class(class_obj3) class Course: def __init__(self,name,period,price): self.name=name self.period=period self.price=price def tell_info(self): print('<课程名:%s 周期:%s 价钱:%s>' %(self.name,self.period,self.price)) # 三:课程 # 创建课程 course_obj1=Course('python全栈开发','6mons',20000) course_obj2=Course('linux运维','5mons',18000) # 为班级关联课程对象 class_obj1.related_course(course_obj1) class_obj2.related_course(course_obj2) class_obj3.related_course(course_obj1) school_obj1.tell_class() #==========================老男孩魔都校区=========================== #脱产14期 <课程名:python全栈开发 周期:6mons 价钱:20000> #脱产15期 <课程名:linux运维 周期:5mons 价钱:18000> school_obj2.tell_class() #==========================老男孩帝都校区=========================== #脱产29期 <课程名:python全栈开发 周期:6mons 价钱:20000>
封装
封装是面向对象三大特性最核心的一个特性
封装就是整合
封装的属性进行隐藏
1、如何隐藏:在属性名前加__前缀,就会实现一个对外隐藏属性效果
该隐藏需要注意的问题:
I:在类外部无法直接访问双下滑线开头的属性,但知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,
所以说这种操作并没有严格意义上地限制外部访问,仅仅只是一种语法意义上的变形。
class Foo: __x = 1 # _Foo__x def __f1(self): # _Foo__f1 print('from test') print(Foo._Foo__x) #1 print(Foo._Foo__f1) #<function Foo.__f1 at 0x00000000026CE3A0>
II:这种隐藏对外不对内,因为__开头的属性会在检查类体代码语法时统一发生变形(一起发生变形)
class Foo: __x = 1 # _Foo__x = 1 def __f1(self): # _Foo__f1 print('from test') def f2(self): print(self.__x) # print(self._Foo__x) print(self.__f1) # print(self._Foo__f1) obj=Foo() #1 obj.f2() #<bound method Foo.__f1 of <__main__.Foo object at 0x00000000022F99D0>>
III: 这种变形操作只在检查类体语法的时候发生一次,之后定义的__开头的属性都不会变形
class Foo: __x = 1 # _Foo__x = 1 def __f1(self): # _Foo__f1 print('from test') def f2(self): print(self.__x) # print(self._Foo__x) print(self.__f1) # print(self._Foo__f1) Foo.__y=3 #定义完 再添加进去的不会变形了 print(Foo.__y) #3
为何要隐藏
I、隐藏数据属性"将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制:
# 设计者 class People: def __init__(self, name): self.__name = name def get_name(self): # 通过该接口就可以间接地访问到名字属性 print(self.__name) def set_name(self,val): #接口之上可以附加额外的逻辑来对数据的操作进行严格地控制 if type(val) is not str: print('小垃圾,必须传字符串类型') return self.__name=val # 使用者 obj = People('egon') obj.get_name() #egon obj.set_name(123123123) #小垃圾,必须传字符串类型
II、隐藏函数/方法属性:目的的是为了隔离复杂度
class ATM: def __card(self): #插卡 print('插卡') def __auth(self): #身份认证 print('用户认证') def __input(self): #输入金额 print('输入取款金额') def __print_bill(self): #打印小票 print('打印账单') def __take_money(self): #取钱 print('取款') def withdraw(self): #取款功能 self.__card() self.__auth() self.__input() self.__print_bill() self.__take_money() obj=ATM() obj.withdraw() #插卡 #用户认证 #输入取款金额 #打印账单 #取款

浙公网安备 33010602011771号