【1】什么是面向过程?
面向过程的核心就是在于 '过程' 两个字,过程的含义就是将程序流程化。过程就是流水线操作,按照步骤来解决问题,过程就是指先干什么,再干什么,继续干什么,最后再做什么。
【2】面向过程的优点
将复杂的问题流程化,进而简单化,一步接一步地解决问题。
【3】面向过程的缺点
一套流水线或者流程就是用来解决某一个确定的问题,比如生产汽车的流水线就只能生产汽车,而没有办法生产可乐。要是想改这条流水线的功能,就需要重新设计。
【1】什么是面向对象?
面向对象的核心就是在于 '对象' 两个字,对象的含义就是某一个整体。对象就是容器,可以盛放我们所需要的数据和功能方法。
【2】例子
面向对象 就相当于 女娲,女娲 可以捏人 ---> 造人。
于是为了解决枯燥的问题 女娲 又造了动物 山水实物 ....
从这里可以看出 人就是具体的对象 而 女娲就是造对象的 类。
【3】面向对象的优点
解决了程序的扩展性;将某个类的属性和方法集合到一起;如果某个类需要添加新的功能,只需要修改这个类即可。
【4】面向对象的缺点
面向对象的过程比较复杂,你必须先明白当前这个类都有哪些属性和功能。
三、初始化属性__init__的推导
class Student:# 这里定义的是当前这个人的属性 ---- 数据属性,都是类属性name = ""school = "清华"age = Nonegender = ""# 当前定义的是这个人的功能 --- 功能属性,也就是方法# 跑步def run(self):print(f"正在跑步")# 游泳def swim(self):print(f"正在游泳")# 读书def read(self):print(f"正在读书")# obj:就是object(对象),也就是说这个参数必须是对象实例# init_obj_obj:类级别的自定义初始化函数def init_obj_obj(obj, name, age, gender):obj.__dict__.update({"name": name,"age": age,"gender": gender})# cls:接收一个类(比如 Student类本身),也就是传给cls的要是一个类本身def init_obj_cls(cls, name, age, gender):# 创建这个类的空对象,赋值给变量 obj,# 比如传入 cls的是Student类本身,则:obj = Student()obj = cls()obj.__dict__.update({"name": name,"age": age,"gender": gender})return obj# 【1】方案一 : 将初始化后的对象给函数进行赋值# 先生成对象student_one = Student()# 将对象和属性全部扔进去进行初始化 返回值是可以为空的init_obj_obj(obj=student_one, name="dream", age=18, gender="男")student_two = Student()init_obj_obj(obj=student_two, name="opp", age=28, gender="女")''''''# 【2】方案二:将类给函数 由类进行产生对象然后赋值# 在函数内部生成空对象然后再对空对象初始化属性 得到 初始化后的对象student_two = init_obj_cls(cls=Student,name="opp",age=28,gender="女")print(student_two.__dict__)
【2】提取功能赋给容器(类)
class Student:# 这里定义的是当前这个人的属性 ---- 数据属性name = ""school = "清华"age = Nonegender = ""# 当前定义的是这个人的功能 --- 功能属性# 跑步# 用学生对象本身调用该方法def run(self):print(self)print(f"正在跑步")# 游泳def swim(self):print(f"正在游泳")# 读书def read(self):print(f"正在读书")# self,表示当前对象,#self代表调用该方法的那个具体对象,修改self的属性就是修改对象本身的属性。def init_obj(self, name, age, gender):#update方法:把传入的字典键值对,添加/更新到 self 的属性中self.__dict__.update({"name": name,"age": age,"gender": gender})# 没有返回值def init_cls(self, name, age, gender):self.__dict__.update({"name": name,"age": age,"gender": gender})# 有返回值 并且 返回值是初始化好的对象return selfstudent = Student()print(student) # <__main__.Student object at 0x12a39ffd0>student.run() # <__main__.Student object at 0x12a39ffd0># self 和 实例化类得到的对象 函数内存地址都是一样的# 所以 self 就是当前对象'''# 【1】方案一 : 在类内部定义初始化当前对象的初始化属性student = Student()student.init_obj(name="dream", age=18, gender="男")# {'name': 'dream', 'age': 18, 'gender': '男'}print(student.__dict__)# 【2】方案二 : 实例化类得到一个初始化好的对象student_one = Student().init_cls(name="opp",age=28,gender="女")#{'name': 'opp', 'age': 28, 'gender': '女'}print(student_one.__dict__)
【3】__init__方式一
class Student:# 这里定义的是当前这个人的属性 ---- 数据属性school = "清华"def __init__(self, name, age, gender):# 通过 __dict__.update() 给当前对象(self)批量绑定实例属性# self.__dict__ 是对象的属性字典,存储该对象的所有实例属性# update()方法可以把一个字典中的键值对批量添加/更新到 self.__dict__ 中self.__dict__.update({"name": name,"age": age,"gender": gender})# 当前定义的是这个人的功能 --- 功能属性# 跑步def run(self):print(f" {self.name} 正在跑步")# 游泳def swim(self):print(f"正在游泳")# 读书def read(self):print(f"正在读书")# 【1】方案一 : 在类内部定义初始化当前对象的初始化属性student = Student(name="dream", age=18, gender="男")# {'name': 'dream', 'age': 18, 'gender': '男'}print(student.__dict__)# 【2】方案二:对象允许 .属性名 取值 还支持 对象.属性名= 属性值替换值student.name = "opp"print(student.__dict__)student.run()
深度解析__init__的作用
当执行 stu = Student("小明", 18, "男") 时,Python 会自动做两件事:
①、创建一个空的 Student 对象;
②、调用 __init__ 方法,把这个空对象传给 self,再把 "小明"/18/"男" 分别赋值给 name/age/gender 参数;
③、最终返回初始化好的对象,赋值给 stu。
这是Python中标准的对象初始化方式,替代了init_obj/init_cls 等外部函数方法。
注:__init__是python的内置方法,创建对象时自动执行,用于初始化实例属性。
深度解析self.__dict__.update()
①、这行代码的作用和逐行赋值是完全一样的,等价于下面的代码:
# 等价于下面三行逐行赋值self.name = nameself.age = ageself.gender = gender
②、update() 的好处是:如果有大量属性需要初始化,写字典的方式更整洁,不用重复写 self.xxx = xxx。
注:self.__dict__.update() 是批量给对象绑定 name/age/gender 实例属性的简洁写法,等价于逐行赋值,如:self.name = name 等。
需要注意:字典不允许 .属性名 取值。
user_data = {"name":"Dream"}# AttributeError: 'dict' object has no attribute 'name'print(user_data.name)
【4】__init__最终版
class Student:# 这里定义的是当前这个人的属性 ---- 数据属性school = "清华"#self.属性名 = 参数 是一种属性赋值方式,等价于 __dict__.update()# self代表当前对象,通过它绑定的属性只属于这个对象,不同对象值可不同def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = gender# 当前定义的是这个人的功能 --- 功能属性# 跑步def run(self):print(f" {self.name} 正在跑步")# 游泳def swim(self):print(f"正在游泳")# 读书def read(self):print(f"正在读书")# 【1】方案一 : 在类内部定义初始化当前对象的初始化属性student = Student(name="dream", age=18, gender="男")# {'name': 'dream', 'age': 18, 'gender': '男'}print(student.__dict__)# 【2】方案二:对象允许 .属性名 取值 还支持 对象.属性名= 属性值替换值student.name = "opp"print(student.__dict__)student.run()
四、类属性与对象属性
# __init__ 方法:初始化对象的独有属性class Student:'''生成学生类'''# 数据属性school = "清华大学"# 函数属性def __init__(self, name, age):self.name = nameself.age = agedef show(self):print(f"{self.name} 正在看电影!")# 实例化类传入参数 实例化 得到一个对象student = Student(name="dream", age=18)# 通过 __dict__ 方法查看当前对象的名称空间print(student.__dict__) # {'name': 'dream', 'age': 18}# 查看当前类的名称空间print(Student.__dict__) # 'school': '清华大学'# 返回一个对象的所有属性和方法名称的列表print(dir(Student))# 【1】获取当前类的名称空间 __dict__print(Student.__dict__)# 【2】获取当前类的文档注释字符串 __doc__print(Student.__doc__)# 【3】获取当前类的名字print(Student.__name__)# 【4】查看当前类所在的模块名字print(Student.__module__)# 【5】查看当前类进程的所有父类 默认是 objectprint(Student.__bases__) # (<class 'object'>,)# 【6】查看当前类所继承的第一个父类print(Student.__base__)# 【7】查看当前对应的类 type 产生了每一个基类print(Student.__class__) # <class 'type'>