面向对象
1.面向过程
面向过程:是一种编程思想,在写代码的时候要时刻想着过程这两个字,什么是过程呢?过程值的就是解决问题的步骤流程,即第一步干什么,第二步干什么的过程。其目的是将一个复杂的问题,拆分为若干的小的问题,按步骤一一解决,也可以说,将一个复杂的问题,流程化(为其制定一个固定的实现流程),从而变得简单。
面向过程编程的优缺点
优点:将复杂的问题简单化
缺点:1.牵一发动全身:流程的固定性,一旦程序中间的一个步骤被修改,将导致整体都需要修改。
2.扩展性差,维护性差
面向过程的应用场景
对扩展性要求比较低的软件,比如系统内核,脚本程序等。
2.面向对象
面向对象:是一种编程思想,缩写OOP,英文 Object oriented Programing,将程序看做一堆对象的集合,实现功能的方式就是对象与对象之间交互。面向对象思想中最核心的概念就是类与对象。
什么是对象:对象指的是具备某些特征与技能的结合体,是实实在在存在的具体物体。
什么是类:类就是类型,类别,分类。类是一个抽象的概念,不实际存在的,是根据一些具备相同特征和技能的对象抽取得到的,比如说人类。
类与对象之间的关系:类包含了一系列相同特征和技能的对象,对象是属于某个类的实例。
面向对象的本质:使用不同的对象来完成程序。
先有类还是先有对象?
在生活中:是先有对象,再根据对象的特征和技能,得到一个类
在程序中:先有类,才能通过类来产生对象,要先确定对象具备什么特征和具备什么技能才能产生对象。
面向对象的优缺点
优点:1.不用考虑繁琐的中间步骤,只需要能得到结果就行了
2.扩展性高,当需要添加一个新功能时,添加一个具有新功能的对象,命令它去完成任务
3.各个对象之间耦合度低,当其中一个对象出了问题,不会对其他对象产生影响
4.可维护性高
缺点:1.面向对象的复杂度比面向过程高
2.无法预知执行结果
面向对象的应用场景
当程序需要较高的扩展性的时候可以使用面向对象编程
为什么要使用面向对象?
因为在当前情况下,大多程序都在与用户打交道,而用户的需求千变万化,程序的扩展性就必须相应的提升,所以选择使用面向对象更加合适。
class Student: #用变量描述特征 school="北京大学" name="张三" age=22 sex="男" stu1=Student() stu2=Student() print(stu1) print(stu2) print(id(stu1)) print(id(stu2)) >>>: <__main__.Student object at 0x0000018DB67E1048> <__main__.Student object at 0x0000018DB6607F60> 1708163731528 1708161793888 stu1和stu2都是Student类的对象,他们都有Student类的特征,但是他们的内存地址不同
class Student: school="北京大学" name="张三" age=22 sex="男" stu1=Student() stu2=Student() stu1.name="李四" print(stu1.__dict__) #对象.__dict__可以查看对象中的特征 print(stu2.__dict__) #stu2中没有修改特征,所以他的特征来自于类, # 因此此时对象中没有特征值,他的特征值在类中 >>>: {'name': '李四'} {}
3.初始化函数
在定义类和实例化对象中发现了一个问题,如果将类中的特征定义成变量=值的形式,进行实例化时如果对象不进行修改特征,对象中的特征永远都是定义类时的特征,就算是进行了修改,加入一个类有很多特征,那么便需要实例化时便需要对对象的特征进行一个一个的修改,这样明显是不对的。初始化函数便是解决这个问题的办法。初始化函数本质是对函数传参数,然后进行赋值的过程,但是初始化函数与普通函数的最大不同就是它能在不被对象调用的情况下执行。在对象实例化时,初始化函数会执行,完成特征的赋值。初始化函数必须命名为 __init__(self,)的形式。
class Person: # 初始化函数名称是固定 该函数会在调用类是时自动执行,self参数必须有,表示要进行初始化的对象,系统会自动传值 def __init__(self,name,age): print("执行了 __init__") print(self) self.name = name self.age =age p1 = Person("张三丰",80) print(p1.__dict__) p2 = Person("李狗蛋",20) print(p2.__dict__) # init 函数用于初始化对象,它会在创建对象时,自动执行,并传入调用类时传递的参数,第一个参数表示要初始化的对象本身, # self(第一个)参数不需要手动传递 # self表示对象自己 是一个形式参数,名字可以随便取,但是不建议修改 >>>: 执行了 __init__ <__main__.Person object at 0x00000279C6439898> {'name': '张三丰', 'age': 80} 执行了 __init__ <__main__.Person object at 0x00000279C64392E8> {'name': '李狗蛋', 'age': 20}
4.绑定方法
绑定方法分为2类:1.绑定给对象的方法 2.绑定给类的方法
把对象和函数进行绑定。
为什么要把对象和函数进行绑定:调用函数就变成了调用对象的方法
对象本质上就是一种存放数据的容器,函数是用于处理数据的代码。绑定方法就是将数据与处理数据的函数绑定在一起。
为什么要把数据和处理数据的函数绑定在一起?
不绑定会出现什么一下问题:
1.问题参数问题,必须手动传递,很有可能传参顺序错误而导致程序错误。
2.每次处理数据,都需要手动传参数
3.当要处理的数据特别多的时候,就不能再定义为变量了,使用列表的方式存储数据可以解决数据多这个问题,但是每一次处理数据都需要先获取数据在传递给处理数据的函数。
所以才要将数据和处理数据的函数绑定在一起,简化代码,提高开发效率。
class Student: school='北京大学' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def learning(self): print("%s正在学习!!!"%self.name) stu1=Student("张三",18,"男") stu1.learning() >>>: 张三正在学习!!!
#使用装饰器classmethod class Student: school='北京大学' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex @classmethod def show_school(cls): print(cls.school) #利用函数展示学校 stu1=Student("张三",18,"男") stu1.show_school() >>>: 北京大学 这个代码本身这么使用没有任何意义,只是为了模拟一下绑定给类的方法的过程。
对象绑定方法 可以使用对象来调用 也可以使用类名来调用
在对象调用时会自动传入对象自己
类调用时不会自动传参,需要传入对象参数
类的绑定方法,对象和类都能调用,并且都会自动传入这个类
什么时候绑定给对象?什么时候绑定给类?
当要处理的数据包含在类中时,就应该绑定类
当要处理的函数包含在对象中时,就应该绑定给对象
类的绑定方法和对象的绑定方法的相同与不同
相同点:1.都会自动传值
2.都可以被类和对象调用
不同点:1.对象绑定方法再对象调用时,传的是对象自己,而类绑定方法是传的是类自己
2.对象绑定方法中第一个参数为self,类绑定方法中第一个参数是cls
5.非绑定方法
在类中即不绑定给类,也不绑定给对象的方法称之为非绑定方法。
特点:没有自动传入参数的效果,类和对象都能调用,就是一个普通的函数,只是定义在类内。
当一个功能不需要访问类的数据,也不需要访问对象的数据时,就可以作为一个非绑定方法。
非绑定方法的使用场景较少
非绑定方法使用装饰器 staticmethod
#使用装饰器classmethod class Student: school='北京大学' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex @staticmethod def test(): print("from test") stu1=Student("张三",18,"男") stu1.test() >>>: from test
小练习:
'''
1.创建Student类
2.拥有以下属性: 姓名 性别 年龄 学校 班级
3.拥有以下方法
save(name) 其作用是将这个对象序列化到文件中
get_obj(name) 其作用是根据name从文件中反序列化为得到一个对象
分析save方法和get_obj 应该作为绑定给对象还是绑定给类
'''
import json class Student: school = "oldboy" def __init__(self, name, age, sex, classes): self.name = name self.age = age self.sex = sex self.classes = classes def save(self): student_dic = {"姓名": self.name, "性别": self.sex, "年龄": self.age, "学校": self.school, "班级": self.classes} with open(self.name, 'wt', encoding='utf-8')as f: json.dump(student_dic, f) @staticmethod def get_obj(name): with open(name, 'rt', encoding='utf-8')as f: student_dic = json.load(f) obj = Student(student_dic.get("姓名"), student_dic.get("年龄"), student_dic.get("性别"), student_dic.get("班级")) return obj stu1 = Student("egon", 18, "man", "py5") stu1.save() stu2 = Student("alex", 98, "man", "py5") stu2.save() stu3 = Student.get_obj("alex") print(stu3.__dict__)