ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ``` 面向过程:(流水线思维方式) 1.让小哥去买雪碧,他去买雪碧的过程都是精确控制的,从头到尾一步一步去完成 2.吃烤鸭,自己去养鸭子,杀鸭子,自己烤鸭子.自己吃.中间过程每一个步骤都是自己去实现 特点: 1.过于注重步骤和过程,不注重职责分工 2如果代码需求很复杂,代码不便于管理 3.开发复杂项目,没有固定套路,不适合开发大型项目 面向对象:(上帝式思维方式) 1让小哥去买雪碧,不需要精确控制买雪碧的过程,由小哥自己去决定 2.吃烤鸭,自己去卖鸭子的店里买烤鸭。烤鸭的制作过程有店里老板完成 我们自己不需要参与 特点: 1注重对象和职责,不同的对象完成不同的功能 2.更加适合复杂的业务需求,尤其是大型项目 3.面向对象的编程思维方式在面向过程的编程思维方式基础之上 ``` ``` 类:(飞机图纸-->类) 1.类是一组具有相同特征和行为的统称,是一个抽象的概念 特征-->属性-->变量 (飞机的长宽高,飞机的颜色) 行为-->方法-->函数 (飞机的飞翔,飞机的滑翔,飞机的翻转) 对象:(一架架具体存在的飞机-—>对象) 1.就是由创建出来的一个个具体存在的事物 对象中也具有属性-->静态的特征 对象中也有 方法-->动态的行为 人类:(抽象的概念) 特征:姓名,年龄,身高,体重 -->特征-->属性-->变量 行为:吃,走,睡觉,工作 -->行为-->方法-->函数 ``` ``` 对象:(具体存在的) 坐着的小明 开车的小王 唱歌的小红 对象中都有自己的属性和方法 每个对象的属性和方法的结果可能各不相同 类和对象的关系: 1.类是模板,通过类可以创建出来一个个具体存在的对象 2.先有类,再有对象(对象是由类创建出来的) 3.类一般只有一个,对象可以有多个 4.类中有的属性和方法,对象也具有属性和方法 ``` ``` 设计类满足的三要素: 1.类名,这类事物抽象的统称,是这类事物的名字 要满足大驼峰命名法(每个单词的首字母都要大写) 2.属性---这类事物具有的特征--->名词,静态的特征 3.方法---这类事物具有的行为--->动词,动态的行为 ``` ``` #类的设计 小明---->对象 小明---->姓名---->静态的描述---->属性 18岁---->年龄---->静态的描述---->属性 1.75---->身高---->静态的描述---->属性 跑----> 动态的行为---->方法 吃----> 动态的行为---->方法 小美---->对象 小美---->姓名---->静态的描述---->属性 17岁---->年龄---->静态的描述---->属性 1.65---->身高---->静态的描述---->属性 吃----> 动态的行为---->方法 人类: 姓名---->静态的描述---->属性 年龄---->静态的描述---->属性 身高---->静态的描述---->属性 吃 ---->动态的行为---->方法 Person name age high run() eat() ``` ``` dir()函数 1.python中内置的函数 2.可以来查看变量/对象/数据 的所有属性和方法 常见的魔法方法: 01 __new__ 方法 创建对象时,会被 自动 调用(公司新入职的职工,分配工位,分配空间) 02 __init__ 方法 对象被初始化时,会被 自动 调用(在分配工位的基础上,配置电脑和办公工具) 03 __del__ 方法 对象被从內存中销毁前,会被 自动 调用(从当前公司离职或跳槽,把配置电脑和办公工具等交还给人事室部门) 04 __str__ 方法 返回对象的描述信息, print函数输出使用(在公司中对某个职工的概述信息) ``` ``` 重点: 类的定义: 1.语法: class 类名: def 方法名1(self,参数列表): print("---方法执行语句代码---") def 方法名2(self,参数列表): print("---方法执行语句代码---") 2.类名要符合大驼峰命名法 3.类是可以封装函数,是比函数更大的封装,面向对象三个特性之一就是封装 类模板创建对象: 对象变量名 = 类名() 访问方法: 对象名.方法名(参数) 对象变量名保存的是对象内存地址的引用 ``` <details> <summary>01_定义简单的类.py</summary> ``` # 01_定义简单的类 # 定义函数 def func(): print("----func--函数--") func() # 定义类模板 class Person: # 当定义方法时,PyCharm自动添加self参数 def run(self): print("-----跑方法------") def eat(self, food): print("------吃方法_吃:%s-----" % food) def sleep(self): print("------睡觉的方法-----") # 使用类模板创建对象 # 对象变量 = 类名() xiao_ming = Person() # 通过对象来调用方法 # 对象变量名.方法名() # 注意:调用方法时,self参数不需要我们传递,由python解释器自动传递 xiao_ming.run() xiao_ming.eat("鸡腿") ''' 函数和方法的区别: 1.相同点:都是封装代码的整体(都是实现某个功能的小工具) 2.不同点: ①.定义位置不同 函数定义在类外部 方法定义在类内部 ②.参数不同 函数没有self参数 方法有self参数 ③.调用方式不同 函数名(参数) 对象名,方法名(参数) ''' ``` </details> <br /> <details> <summary>02_第一个面向对象程序.py</summary> ``` # 02_第一个面向对象程序 # 探究 类中方法的调用 # 定义类模板 class Cat: '''猫类''' print("------类模板初始化几次?-----") def eat(self): print("小猫爱吃鱼") def drink(self): print("小猫要喝水") tom = Cat() tom.eat() ''' 方法的调用顺序总结: 1.定义类模板时, Python解释器会进入类模板内部扫描一遍,定义方法 不会进入方法内部执行代码,类模板只被初始化一次 2.当使用类模板创建对象,通过调对象名,方法名()调用方法时, 才会进入方法内部执行代码 3.方法中的代码执行完后,回到调用调用的地方,继续向下执行 ''' ``` </details> <br /> <details> <summary>03_self参数.py</summary> ``` # 03_self参数 class Cat: ''' 当前是猫类,只包含方法 ''' def eat(self): print("小猫爱吃鱼", self) def drink(self, water): print("小猫要喝%s" % water) tom_cat = Cat() tom_cat.eat() print("-" * 30) lazy_cat = Cat() lazy_cat.eat() ``` </details> <br /> ``` 地址的进制表示 1.十进制 %d 2.十六进制 %x 获取变量的引用的内存地址 id(变量) #给对象添加属性有两种方式 1.在类外部给对象添加属性 方式: 对象.属性名 = 属性值 添加完属性后,访问方式: 1).在类的内部 可以使用self参数访问属性 se1f.属性名 2).在类的外部 通过对象访问属性 对象名.属性名 2.在类内部给对象添加属性 ---> 待定 3.给对象添加属性,属性添加到对象的内存空间中了 重点: self参数的小结 1.self参数保存当前对象的引用地址,(哪个对象调用方法,self参数保存的就是哪个对象的引用地址) 2.在类的内部 访问属性 self.属性名 在类的内部 调用方法 self,方法名(参数) 3.在类的外部 访问属性 对象名.属性名 在类的外部 调用访问 对象名.方法名(参数) ``` <details> <summary>04_在类的外部给对象添加属性.py</summary> ``` # 04_在类的外部给对象添加属性 class Cat: ''' 猫类 ''' def eat(self): # 在类的内部访问属性 通过self.属性名 print( "%s 爱吃鱼" % self.name) # 在类的内部访问方法 通过 self.方法名(参数) self.drink("雪碧") def drink(self, water): print("小猫要喝:%s" % water) tom = Cat() # 在类外给对象添加属性 # 对象名.属性名 = 属性值 tom.name = "汤姆猫" # 在类的外部访问属性 # 对象名.属性名 print(tom.name) # 对象名.方法名() tom.eat() ``` </details> <br /> ``` 初化方法__init__小结: 1.作用:主要用来初始化属性数据的 2.特点:在使用类模板创建对象时,自动调用 在使用类模板创建对象时,完成了两个过程: 类名() 1.给对象分配内存空间 2.调用__init__方法初始化属性数据 ``` <details> <summary>06_初始化__init__方法的使用.py</summary> ``` # 目标:06_初始化__init__方法的使用 class Cat: '''猫类''' def __init__(self): ''' 初始化方法 __init__初始化方法主要用来初始化数据的 初始化属性数据的 初始化方法在 使用类模板创建对象时自动调用 ''' print("1.__init__初始化方法主要用来初始化数据的") def eat(self): print("小猫爱吃小鱼干") tom = Cat() ``` </details> <br /> ``` 在类的内部给对象添加属性: 在初始化方法的内部添加属性 1.在__init__方法中,self,属性名 = 属性初始值 添加属性 2.属性添加到对象的内存空间中了 3.当使用 类模板创建 对象时(类名()),初始化方法__init__会自动调用, 属性自动添加到对象的内存空间中了 ``` <details> <summary>07_在初始化方法的内部添加属性.py</summary> ``` # 07_在初始化方法的内部添加属性 class Cat: '''猫类''' def __init__(self): print("1.__init__初始化方法主要用来初始化数据的") # 在类的内部添加属性 self.属性名 = 属性初始值 self.name = "汤姆猫" print("2.初始化方法在 使用类模板创建对象时自动调用") def eat(self): print("%s 爱吃小鱼干" % self.name) tom = Cat() print(tom.name) tom.eat() ``` </details> <br /> ``` 在初始化的同时设置属性值 1.在__init__()方法中添加形参,__init__(self.形参): 2.在__init__()方法中,把形参保存为属性 self.属性名=形参 3.使用 类模板创建对象时,一定要传递参数 类名(实参) ``` <details> <summary>08_在初始化的同时设置属性值.py</summary> ``` # 08_在初始化的同时设置属性值 class Cat: def __init__(self, new_name): self.name = new_name def eat(self): print("%s 爱吃小鱼干" % self.name) tom = Cat("汤姆猫") tom.eat() bosimao = Cat("波斯猫") bosimao.eat() ``` </details> <br /> <br /> ### **初始化方法的小结:** ``` 1.概念:__init__()方法就是初始化方法(魔法方法) 2.作用:就是用来初始化数据的 3.特点:使用类模板创建对象时,会自动调用 4.在__init__方法中添加属性 self.属性名 = 属性值 5.在初始化的同时,设置属性值 ①.在__init__(self,形参) 方法中添加参数 ②.在_init_(seLf,形参)方法中把参数保存为属性 self.属性名=形参 ③.使用类模板创建对象时,一定要传递参数 类名(参数) ``` <details> <summary>__del__ 方法.py</summary> ``` # __del__ 方法: # 当前程序退出时,对象从内存空间销毁前,自动调用 # 作用:清除资源的操作 class Cat: '''猫类''' def __init__(self, name): self.name = name def eat(self): print("%s 爱吃小鱼干" % self.name) def __del__(self): '''删除的魔法方法''' print("当前程序退出时,对象从内存空间销毁前,自动调用") print("清除资源的操作") tom = Cat("汤姆猫") # 注意:__del__ 魔法方法在程序退出之前自动调用 # __del__ 魔法方法 可以手动调用 del tom ``` </details> <br /> <details> <summary>02_魔法方法__del__的使用场景.py</summary> ``` # 目标:实现 02_魔法方法__del__的使用场景 # 当前程序退出时,对象从内存空间销毁前,自动调用 # 作用:清除资源的操作,文件的资源,网络套接字资源,数据库连接资源 class Cat: '''猫类''' name: object def __init__(self, name): self.name = name def eat(self): # self.food = food print("%s 爱吃小鱼干" % self.name) # 局部变量作用范围只能是当前方法,如果想让下面的方法访问到当前的属性 # 需要把局部变量保存为属性 self.file = open("cat.txt", 'w', encoding="utf-8") self.file.write("%s 爱吃小鱼干" % self.name) def __del__(self): '''删除的魔法方法''' print("当前程序退出时,对象从内存空间销毁前,自动调用") print("清除资源的操作") print("---1--文件关闭前---") self.file.close() print("---2--文件关闭后---") tom = Cat("汤姆猫") tom.eat() # 注意:__del__ 魔法方法在程序退出之前自动调用 # __del__ 魔法方法 可以手动调用 del tom ``` </details> <br /> ``` 魔法方法__del__小结: 1.特点:当前程序退出时,对象从内存空间销毁前,自动调用__del__ 2.作用:清除资源的操作,文件的资源,网络套接字资源,数据库连接资源等 对对象的生命周期: 1.从使用类模板创建对象时开始,到自动调用__del()__方法结束 魔法方法 __str__ 1.特点:打印对象时,自动调用, print(对象名) __str__()方法会自动调用 2.作用:打印对象的描述信息 3.注意:__str__方法必须有返回值,只能返回字符串 返回值 返回到 print(对象名) 地方 ``` <details> <summary>03_魔法方法__str__使用.py</summary> ``` # 目标:实现03_魔法方法__str__使用 # __str__方法: # 特点:打印对象时,自动调用 print(对象名)__str__()方法会自动调用 # 作用:打印对象的描述信息 # 注意:__str__方法必须有返回值,只能返回字符串 class Cat: '''猫类''' name: object def __init__(self, name): self.name = name def eat(self): # self.food = food print("%s 爱吃小鱼干" % self.name) def __str__(self): '''对象描述信息方法''' print("使用print()方法,打印对象时,自动调用") return "名字是:%s" % self.name # return 100 # Error __str__方法只能返回字符串 # 使用类模板创建对象 big_face_cat = Cat("大脸猫") print(big_face_cat) ``` </details> <br /> <br /> <details> <summary>案例1.py</summary> ``` # 04_小明爱跑步案例 class Person: def __init__(self, name, weight): self.name = name self.weight = weight def __str__(self): return "姓名是:%s 体重是:%.2f" % (self.name, self.weight) def run(self): print("%s 爱跑步,每次跑步减重0.5公斤" % self.name) self.weight -= 0.5 def eat(self): print("%s 是一个吃货,每次吃东西,体重增加1公斤" % self.name) self.weight += 1 xiaoming = Person("小明", 75.0) print(xiaoming) xiaoming.run() print(xiaoming) xiaoming.eat() print(xiaoming) print("-" * 50) xiaomei = Person('小美', 45.0) xiaomei.run() print(xiaomei) xiaomei.eat() print(xiaomei) 运行结果: 姓名是:小明 体重是:75.00 小明 爱跑步,每次跑步减重0.5公斤 姓名是:小明 体重是:74.50 小明 是一个吃货,每次吃东西,体重增加1公斤 姓名是:小明 体重是:75.50 -------------------------------------------------- 小美 爱跑步,每次跑步减重0.5公斤 姓名是:小美 体重是:44.50 小美 是一个吃货,每次吃东西,体重增加1公斤 姓名是:小美 体重是:45.50 ``` </details> <br /> <details> <summary>案例2.py</summary> ``` # 05_摆放家具案例 class HouseItem: '''家具类''' def __init__(self, name, area): self.name = name self.area = area def __str__(self): '''打印家具对象的描述信息''' return "家具名字:%s, 占地面积:%.1f平米" % (self.name, self.area) bed = HouseItem("席梦思", 4) print(bed) chest = HouseItem('衣柜', 2) print(chest) table = HouseItem("餐桌", 1.5) print(table) class House: '''房子类''' def __init__(self, house_type, area): self.house_type = house_type self.area = area self.free_area = area self.item_list = [] def __str__(self): return ("户型:%s, 总面积:%.1f平方米, 剩余面积:%.1f平方米, 家具名称列表:%s " % (self.house_type, self.area, self.free_area, self.item_list)) def add_item(self, item): print("item", item) print("item.name", item.name) print("item.area", item.area) # 1.判断房子的剩余面积和家具的面积大小 # 如果房子的剩余面积小于家具的面积,不能添加,给个提示信息,代码不再向下执行 if self.free_area < item.area: print("添加 %s 家具的面积太大,无法添加!!" % item.name) return # 如果房子的剩余面积不小于家具的面积,可以添加家具 # 2.更新房子的剩余面积 self.free_area -= item.area # 3.把新添加的家具名称保存到 家具名称列表 self.item_list.append(item.name) big_house = House("别墅", 90) print(big_house) big_house.add_item(bed) print(big_house) big_house.add_item(chest) print(big_house) big_house.add_item(table) print(big_house) ---------------------------------------- 打印: 家具名字:席梦思, 占地面积:4.0平米 家具名字:衣柜, 占地面积:2.0平米 家具名字:餐桌, 占地面积:1.5平米 户型:别墅, 总面积:90.0平方米, 剩余面积:90.0平方米, 家具名称列表:[] item 家具名字:席梦思, 占地面积:4.0平米 item.name 席梦思 item.area 4 户型:别墅, 总面积:90.0平方米, 剩余面积:86.0平方米, 家具名称列表:['席梦思'] item 家具名字:衣柜, 占地面积:2.0平米 item.name 衣柜 item.area 2 户型:别墅, 总面积:90.0平方米, 剩余面积:84.0平方米, 家具名称列表:['席梦思', '衣柜'] item 家具名字:餐桌, 占地面积:1.5平米 item.name 餐桌 item.area 1.5 户型:别墅, 总面积:90.0平方米, 剩余面积:82.5平方米, 家具名称列表:['席梦思', '衣柜', '餐桌'] ``` </details> <br /> <details> <summary>案例3.py</summary> ``` # 06_士兵突击_优化 class Gun: '''枪类''' def __init__(self, type): self.type = type # 子弹的数量,新枪默认没有子弹 self.bullet_count = 0 def add_bullet(self, count): '''添加子弹的方法''' self.bullet_count += count def shoot(self): '''射击方法''' # 如果没有子弹,不能射击,提示添加子弹,代码不再向下执行 if self.bullet_count <= 0: print("还没子弹,请先添加子弹!!!") return self.bullet_count -= 1 print("%s biubiubiu...剩余子弹数量:%d" % (self.type, self.bullet_count)) # ak47 = Gun("AK47") # # ak47.add_bullet(50) # # ak47.shoot() # ak47.shoot() class Soldier: '''士兵类''' # gun=None 缺省参数(带有默认值的参数) def __init__(self, name, gun=None): self.name = name # 士兵的枪支 新兵默认没有枪支 self.gun = gun def add(self, new_count): '''当前方法是士兵拿着枪添加子弹''' if self.gun is None: print("当前士兵:%s 还没有枪,不能开火,请分配枪支!!" % self.name) return self.gun.add_bullet(new_count) def fire(self): '''开火的方法''' if self.gun == None: print("当前士兵:%s 还没有枪,不能开火,请分配枪支!!" % self.name) return self.gun.shoot() ak47 = Gun("AK47") xsd = Soldier("许三多", ak47) xsd.add(50) xsd.fire() xsd.fire() ``` </details> <br /> ### **身份运算符** ``` is 用来判断两个变量引用地址是否相同 如果相同返回True,否则返回 False == 用来判断两个变量的数据值是否相等 如果相等返回True,否则返回 False Python针对None比较时,建议使用is ``` <br /> ### **私有属性和私有方法:** ``` 1.有些情况下,类中一些属性和方法不需要类外直接访问到,可以把类中的属性和方法定义为私有 2.前置双下划线的属性和方法就是私有属性和私有方法, __age 私有属性, __screat(self) 私有方法 3.私有属性和私有方法在类外部不能直接访问 但是可以在类内部访问到 可以通过self访问 4.Python中并没有真正意义上的私有属性和私有方法, 而是通过名字重整的方式将私有属性和私有方法改了名字 方式: ①私有属性名: _类名__私有属性名 ②私有方法名: _类名__私有方法名 5.可以通过重整后的私有属性名和私有方法名,间接去访问 6 Python中的警告: Python中不阻止你去干坏事,一切靠自觉 7.可以通过对外方法间接访问私有属性,set_age()/ get_age() ``` <details> <summary>07_私有属性和私有方法.py</summary> ``` # 07_私有属性和私有方法 class Woman: '''美女类''' def __init__(self, name): self.name = name # 前置双下划线的属性是私有的属性 self.__age = 20 def eat(self): '''吃方法''' # 在类的内部可以通过self访问私有属性 print("%s 今年%s岁了,是一个吃货" % (self.name, self.__age)) # 在类的内部可以通过self访问私有方法 self.__secret() def __secret(self): '''私有方法''' print("个人秘密,不方便透露...") xian_nv = Woman("仙女") print(xian_nv.name) # 在类的外部无法直接访问私有属性 # print(xian_nv.__age) xian_nv.eat() # 在类的外部无法直接访问私有方法 # xian_nv.__srcreate() ``` </details> <br /> <details> <summary>08_伪私有属性和私有方法.py</summary> ``` # 08_伪私有属性和私有方法 class Woman: '''美女类''' def __init__(self, name): self.name = name # 前置双下划线的属性是私有的属性 self.__age = 20 # 对外提供访问私有属性的接口(方法) get / set def get_age(self): '''获取私有属性值''' return self.__age def set_age(self, new_age): '''设置私有属性值''' if 0 <= new_age or new_age >= 150: print("您输入的年龄有误") return self.__age = new_age def eat(self): '''吃方法''' # 在类的内部可以通过self访问私有属性 print("%s 今年%s岁了,是一个吃货" % (self.name, self.__age)) # 在类的内部可以通过self访问私有方法 self.__secret() def __secret(self): '''私有方法''' print("个人秘密,不方便透露...") xian_nv = Woman("仙女") print(xian_nv.name) # 在类的外部无法直接访问私有属性 # print(xian_nv.__age) # xian_nv.eat() # 在类的外部无法直接访问私有方法 # xian_nv.__srcreate() print(dir(xian_nv)) # Python中并没有真正意义上私有,是通过名字重整的方式,把私有属性和私有方法改了名字 # 私有属性: __私有属性名 ---> _类名__私有属性名 # 私有方法: __私有方法名 ---> _类名__私有方法名 # print(xian_nv._Women__age) # 在类的外部无法直接访问私有属性,可以通过名字重整方式,间接访问 # xian_nv._Woman__secret() # 在类的外部无法直接访问私有方法,可以通过名字重整方式,间接访问 ret = xian_nv.get_age() print(ret) xian_nv.set_age(25) ret = xian_nv.get_age() print(ret) ``` </details> <br />