Python 面向对象高级
1.定义类的几种语法方式1类名方式2类名方式3类名object注意object 是所有类的父亲Python 中所有的类都直接或者间接继承自 object 类小结2.继承2.1 什么是继承继承指子类继承父类的属性和方法派生从一个已有的类产生一个新的类称为派生站在父类角度注意继承指的是类的继承而不是对象的继承继承和派生是从不同角度来描述的相同概念本质是一致的在 Python 中继承形式如下注意在 Python 中所有类默认继承 object 类继承的好处提高了代码的复用率减少代码重复的书写继承的弊端耦合性增强了父类不好的内容子类都继承了2.2 单继承与多继承单继承一个子类只能继承自一个父类不能继承多个类多继承指的是一个子类同时继承了多个父类的情况会将多个父类中的非私有属性和方法都继承下来注意当一个类继承了多个父类时默认优先使用第一个父类中的同名属性和方法可以使用类名._ _mro_ _ 属性或类名.mro() 方法查看调用顺序MROMethod Resolution Order方法解析顺序小结2.3 子类重写父类属性和方法重写也叫作覆盖指子类继承父类后如果父类中的方法不满足需求可以在子类中重新定义父类中已有的方法方法名相同从而用子类的方法实现替换父类的方法实现注意子类覆盖父类的属性和方法后子类创建的实例对象会优先调用子类的属性和方法如果子类在重写父类方法时仍想保留父类的行为需要先调用父类的方法可以通过父类名.方法名self/ super.方法名方式来调用父类名.方法名self精准访问想找哪个父类就调用哪个父类super.方法名只能访问最近的那个父类有就用没有就继续查找2.4 多层继承多层继承一个类继承自另一个子类形成一条继承链。A → B → C3.封装3.1 什么是封装封装将对象的属性和方法封装成一个整体并对外隐藏仅对外提供访问的接口。本质就是将数据属性和操作数据的源代码方法进行结合形成 “类” 其中的数据和函数都是类的成员3.2 私有属性和私有方法私有属性和私有方法在 Python 中可以为属性和方法设置私有权限即设置某个属性或方法不继承给子类这些设置私有权限的属性和方法就是私有属性和私有方法。设置私有属性和方法的方式在属性或方法名前面加上_ _格式如下注意Python中没有真正的私有机制靠命名约定俗成约定在私有属性名和私有方法名前加 _ _(两个下划线私有属性和方法使用规则只能在类的内部使用不能在类的外部使用如果想要在类的外部使用必须通过公共接口私有属性和方法的获取和修改私有属性的获取和修改私有属性不能直接访问在 Python 中一般定义方法名get _xx 用来获取私有属性定义“set _xx” 用来修改私有属性不过这无疑增加了代码量私有方法的访问访问私有方法可以使用重新设置一个公有方法来访问如下所示小结4.多态4.1 什么是多态多态指同一个函数在不同场景下有不同的状态。即同一个函数传入不同的对象得到不同的结果多态成立的3个条件有继承父类子类子类继承父类函数重写子类重写父类的函数父类引用指向子类对象子类对象传给父类对象调用者注意这一套是编译期静态类型语言Java/C#的规则4.2 鸭子类型鸭子类型Duck Typing指如果它走路像鸭子叫起来像鸭子那么它就是鸭子在鸭子类型中我们关注的是对象的行为它有什么方法而不是对象的类型它是什么类Python 是鸭子类型duck typing动态语言不需要继承鸭子类型的优势是不需要存在继承关系只要对象有相应的方法就能使用#狗 class Dog: def __init__(self, name, age): self.name name self.age age def swimming(self): print(f{self.age} 岁的 {self.name} 正在游泳...) #鸭子 class Duck: def __init__(self, name, age): self.name name self.age age def swimming(self): print(f{self.age} 岁的 {self.name} 正在游泳...) #猪 class Pig: def __init__(self, name, age): self.name name self.age age def swimming(self): # 启动 print(f{self.age} 岁的 {self.name} 正在游泳...) #有用函数 def go_swimming(duck: Duck): duck.swimming() # 测试代码 if __name__ __main__: go_swimming(Dog(name旺财, age4)) go_swimming(Duck(name唐老鸭, age2)) go_swimming(Pig(name佩奇, age1))5.抽象类5.1 为什么会有抽象类对于继承和多态的理解继承子类继承父类的属性与方法。好处是提高了代码的复用性坏处是子类与父类的耦合性增强父类不好的内容子类也必须继承多态父类框架下的同一个函数传入不同的子类对象得到不同的结果。好处是应用解耦坏处是 Python 语言下无法精确限定类型无需继承因此为了更好使用多态提出了抽象类抽象接口的概念抽象方法方法体是空实现pass的方法抽象类含有抽象方法的类抽象类的设计目的是抽象类 父类用来确定有哪些方法抽象类 父类制定接口标准具体的方法实现由子类来实现子类实现接口标准6.面向对象的其他属性6.1 对象属性和类属性类属性写在class 内部、方法外面属于整个类所有对象共享同一份数据。可以通过类名. 和 对象名.方式访问。对象属性一般在魔法方法 _ _init_ _ 里用 self.xxx定义每个对象独立一份互不干扰。只能通过对象名. 属性名方式访问class Person: species 人类 def __init__(self, name, age, weight): # 对象属性 self.name name self.age age self.weight weight p1 Person(小明, 18, 60) p2 Person(小红, 19, 50)访问规则优先找对象自己的属性找不到再向上找类属性属性修改对象.属性 值新增 / 修改这个对象自己的实例属性不会改动类属性类名.属性 值修改真正的类属性全部对象都会受影响代码如下p1.species 超人 # 给p1单独增加一个实例species不改变类 print(p1.species) # 超人自己的 print(p2.species) # 人类还是类的 print(Person.species)# 人类 Person.species 智人 # 修改类属性 print(p2.species) # 智人内存示意图Student类一块空间存放类属性s1对象一块独立空间存放自己的实例属性缺省时向上引用类的属性s2对象另一块独立的空间class Student: teacher 水镜先生 def __init__(self, name, age): self.name name self.age age def __str__(self) - str: return f姓名{self.name},年龄{self.age} if __name__ __main__: s1 Student(曹操,38) s2 Student(曹操,38) s1.name 许褚 s1.age 40 s1.teacher 夯哥 Student.teacher 鹏哥6.2 类方法和静态方法类方法指的是类所拥有的方法。可以通过类名.方法名和对象名.方法名的方式来调用装饰器classmethod第一个固定参数cls代表当前类通过cls.***读写类属性注意要求类方法的第一个参数必须是类通常以cls作为第一个参数名class Test: count 0 classmethod def add(cls): cls.count 1静态方法写在类里面但和类、对象本身都没有自动绑定关系的普通函数只是把函数逻辑上归类放到类中。属于该类下所有对象所共有的方法可以通过类名.方法名和对象名.方法名的方式来调用装饰器staticmethod没有默认参数普通函数写法不自动传类/对象不能直接用 self / clsclass Test: staticmethod def show(): print(普通工具函数)类方法和静态方法的区别1. 语法上类方法classmethod第一个参数固定是 cls代表类静态方法staticmethod没有默认参数2. 访问类属性的方式类方法用cls.属性名自动拿到当前类静态方法必须手动写类名.属性名3. 继承的区别最重要考点子类调用时类方法的cls自动变成子类自带多态静态方法写死父类名不会自动变成子类因此如果函数中要使用类本身cls就定义成类方法如果只是一个和类逻辑相关、不需要访问类和实例对象数据的工具函数定义为静态方法如果需要使用实例对象 (self)定义为普通实例方法在实际开发中静态方法较为常用。小结7.面向对象高级案例学生管理系统7.1 需求分析需求(1) 使用面向对象、字符串、列表、字典、文件等知识点来完成一个学生管理系统 V2.0(2) 针对学生该系统具有添加、修改、删除、查询所有学生、查询某个学生、保存信息、退出系统等操作根据操作流程以及系统需求完成面向对象版学生管理系统项目开发a. 可以显示基本的版本信息和操作界面b. 可以通过键盘输入信息来完成基本功能例如选择序号、确认退出、添加学生、修改信息等c. 学生属性信息有姓名、性别、年龄、联系方式、描述信息等d. 使用系统可对学生信息进行添加、修改、删除、查询等操作e. 可以使用文件对学生信息进行加载、保存等f. 可重复对学生进行增删查改操作当确认退出系统后则直接退出系统g. 请使用面向对象的编程思想完成项目的升级处理。7.2 角色分析角色学生 和 学生管理系统 2个类注意事项为了方便维护代码一般一个角色一个程序文件项目要有主程序入口习惯为 “main.py”7.3 代码实现7.3.1 学生类代码编写相应代码如下class Student(object): def __init__(self, name, gender, age, phone_number, description): self.name name self.gender gender self.age age self.phone_number phone_number self.description description def __str__(self): return f姓名{self.name}, 性别{self.gender}, 年龄{self.age}, 联系方式{self.phone_number}, 描述信息{self.description} #测试 if __name__ __main__: student Student(张三, 男, 18, 12345678901, 优秀的学生) print(student)7.3.2 学生管理系统类代码编写显示界面如下搭建项目框架退出系统程序主入口相关代码如下from Student import Student import os class StudentCms(object): def __init__(self): self.students [] #列表存储学生对象 #显示界面菜单 staticmethod def show(): print( ********************************************** 本学生管理系统v2.0功能如下 1. 添加学生 2. 修改学生 3. 删除学生 4. 查询某个学生 5. 显示所有学生 6. 保存信息 7. 退出系统 ********************************************** ) #加载数据库信息 def load_data(self): if not os.path.exists(data): os.mkdir(data) with open(data/students.csv, w, encodingutf-8) as f: f.write(姓名,性别,年龄,联系方式,描述\n) return True else: self.students.clear() # 清空旧数据防止重复叠加 with open(data/students.csv, r, encodingutf-8) as f: try: next(f) # 跳过表头 except StopIteration: return for line in f: name, gender, age, phone_number, description line.strip().split(,) student Student(name, gender, age, phone_number, description) self.students.append(student) #添加学生 def add_student(self): name input(请输入学生姓名) gender input(请输入学生性别) age int(input(请输入学生年龄)) phone_number input(请输入学生电话号码) description input(请输入学生描述信息) student Student(name, gender, age, phone_number, description) self.students.append(student) print(f添加学生信息成功具体信息为{student}) #修改学生 def modify_student(self): while True: name input(请输入要修改的学生姓名) for student in self.students: if student.name name: print(f找到学生{student.name}其修改前信息为{student}) print(您的修改信息如下) student.name input(请输入学生姓名) student.gender input(请输入学生性别) student.age int(input(请输入学生年龄)) student.phone_number input(请输入学生电话号码) student.description input(请输入学生描述信息) print(f修改学生{student.name}信息成功) return True else: print(未找到该学生,请重新输入!) #删除学生 def delete_student(self): while True: name input(请输入要删除的学生姓名) for student in self.students: if student.name name: self.students.remove(student) print(f删除学生{student.name}信息成功) return True else: print(未找到该学生,请重新输入!) #查询某个学生信息 def query_student(self): while True: name input(请输入要查询的学生姓名) for student in self.students: if student.name name: print(f找到学生{student.name}其信息为{student}) return True else: print(未找到该学生,请重新输入!) #显示所有学生信息 def show_all_students(self): print(系统中所有学生信息如下) for student in self.students: print(f{student}) #保存信息 def save_info(self): print(正在保存信息...) #写入文件 with open(data/students.csv, w, encodingutf-8) as f: #遍历写入学生信息 for student in self.students: f.write(f{student.name},{student.gender},{student.age},{student.phone_number},{student.description}\n) print(保存信息成功) #退出系统 def exit_system(self): self.save_info() choice input(确定退出系统么? Y/N\n).upper() if choice Y: print(正在退出系统...) exit() else: print(已取消退出系统) #系统主入口 def run(self): self.load_data() while True: #显示菜单 self.show() choice input(请输入您的选择) if choice 1: self.add_student() elif choice 2: self.modify_student() elif choice 3: self.delete_student() elif choice 4: self.query_student() elif choice 5: self.show_all_students() elif choice 6: self.save_info() elif choice 7: self.exit_system() else: print(输入有误请重新输入) #测试 if __name__ __main__: cms StudentCms() cms.run()
上一篇/下一篇内容由系统自动关联
返回资讯列表 →