文章目录
一、面向对象编程
(一)什么是面向对象编程
面向对象编程是一种编程套路,我们可以来跟面向过程编程做个对比。
1.面向过程编程
面向过程编程的核心是过程,过程指的是做事的步骤,即做事的先后顺序,基于该思想编写的程序,就相当于一条条流水线。
(1)优点
复杂的问题流程化,进而变得简单化。
(2)缺点
扩展性差。
2.面向对象编程
面向对象编程的核心是对象,对象就是一个用来盛放/整合相关数据与相关功能的容器。
(1)优点
程序解耦合强,扩展性好。
(2)缺点
比面向过程复杂,不适合扩展性低的使用场景,容易出现过度设计的问题。
(二)类与对象的使用
1.类与对象是什么
类即类别/种类,是面向对象设计最重要的概念。
对象是数据与功能的集合体。
而类则是对象之间相同数据与功能的集合体。
对象1:
# 学生1的数据
name = "egon"
age = 18
gender = "male"
对象2:
# 学生2的数据
name = "王三炮"
age = 19
gender = "female"
对象3:
# 学生3的数据
name = "李大炮"
age = 20
gender = "male"
学生类:
# 学生对象相同的数据
school = "上海校区"
# 学生对象相同的功能
选课功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amenlRYq-1596528994344)(D:\Onedrive\文档\01学习资料\全栈15博客笔记\python学习博客及作业\day024.面向对象编程\001_r.jpg)]
2.类的定义与使用
(1)在程序中必须先定义类(空间、执行)
定义类的时候,发生了两件事:
①、定义类就是申请内存空间,可以把对象之间共同的数据与功能存起来。
②、类在定义的时候就会立即执行类体代码,会产生类的名称空间,存放属于类的名字(共同的数据及功能),然后类名指向该名称空间。
class Student:
school = "上海校区"
def choose_course(self):
print("正在选课")
# 代码定义后会立即执行
print("====>") # ====>
#
print(Student.__dict__) # {'__module__': '__main__', 'school': '上海校区', 'choose_course': <function Student.choose_course at 0x0000016AE4258040>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
***************需要注意的点:***************
1)类中可以有任意python代码,这些代码在类定义阶段便会执行;
2)因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过Student.__dict__查看
3)点是访问属性的语法,类中定义的名字,都是类的属性
***************需要注意的点:***************
(2)后使用(对象、空间)
调用类来产生对象,调用类的过程又称之为实例化。
调用类的本质:产生一个对象的子内存空间与类相关联,首先关联的是类中公共的功能与数据。
# 定义完类之后,接下来就是调用类来产生对象
stu1 = Student() # 实际上相当于创建了一个空对象 <__main__.Student object at 0x00000228F1CE5B50> print(stu1.__dict__) {}
stu2 = Student()
stu3 = Student()
stu1.__dict__["name"] = "egon" # 对象调用.__dict__功能,用来保存对象属性变量的键值对
# stu1.name = "egon" # 简化下来可以这样写,本质上实现的功能是一样的
stu1.__dict__["age"] = 18
# stu1.age = 18
stu1.__dict__["gender"] = "male"
# stu1.gender = "male"
print(stu1.__dict__) # {'name': 'egon', 'age': 18, 'gender': 'male'}
3.类与对象的本质
类的本质是一个字典,对象的本质也是一个字典,面向对象就是使用字典整合数据,只是python为我们提供了专门的语法,让使用面向对象更简便。
# 大字典————>关联————>小字典
| |
类 对象
| |
共享空间 独有数据
4.使用.__ init __()方法
python为类内置了一系列特殊熟悉:
# 常用的内置属性
类名.__name__ # 类的名字(字符串)
类名.__doc__ # 类的文档字符串
类名.__base__ # 类的第一个父类(在讲继承时会讲)
类名.__bases__ # 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__ # 类的字典属性
类名.__module__ # 类定义所在的模块
类名.__class__ # 实例对应的类(仅新式类中)
类的其他特殊属性
(1)为何要使用.__ init __方法
在调用类的过程中,我们需要给对象定制各自独有的属性,在类实例化之后再增加属性过于繁琐,所以python提供了在类内部增加__ init __ 方法,可以在**实例化(调用类)**的过程中就为对象初始化、传值。
class Student:
school = "上海校区"
# 空对象,"egon",18,"male"
def __init__(self, x, y, z):
self.name = x # 空对象.name="egon"
self.age = y # 空对象.age=18
self.gender = z # 空对象.gender="male"
# print("===>")
# 该函数内可以有任意代码,但是该函数不能返回非None值
# return 123
# stu1
def choose_course(self):
print('%s 正在选课' %self.name)
def func(self,x,y):
print(self.name,x,y)
stu1 = Student("egon",18,"male")
stu2 = Student("王三炮",19,"female")
stu3 = Student("李大炮",20,"male")
(2)调用类时发生了哪三件事?
①、会先创造一个空对象(子空间),并与类相关联;
②、自动触发类内**.__ init __**(空对象,“egon”,18,“male”) 方法,把空对象及数据进行传输,完成对象的初始化;
③、返回一个初始化好的对象,使用赋值符号把对象内存地址绑定给一个变量名(“类_对象”)。
(三)属性访问
1.属性的分类
定义在类中的名字,都是类的属性,可以分为两种:数据属性和函数属性。可以通过__ dict __访问属性的值,但python有专门的属性访问语法。
2.属性的访问
类与对象都可以通过 . 来访问属性来完成增删改查的操作。
(1)访问类的数据属性
Student.school = "Shanghai" # 修改类的属性
Student.xxx = 111 # 增加类的属性
del Student.xxx # 删除类的属性
(2)访问类的函数属性
类的函数它就是一个普通函数,该传几个参数就传几个参数。
print(Student.choose_course) # <function Student.choose_course at 0x00000228E5628280>
Student.choose_course(stu1) # egon 正在选课 传入参数后立即执行
3.属性查找顺序与绑定方法
(1)属性查找顺序/优先级:
先找对象后找类。
对象_._属性,会先从对象自己的空间里找,没有的话去类里面找。
(2)类属性的用途
类中的定义的数据属性为了给对象用的,而且是所有对象共享,大家访问的都是同一个地址。
print(id(Student.school)) # 1702345007920
print(id(stu1.school)) # 1702345007920
print(id(stu2.school)) # 1702345007920
print(id(stu3.school)) # 1702345007920
Student.school = "!!!" # 修改类的数据属性,所有对象都会跟着修改
print(stu1.school) # !!!
print(stu2.school) # !!!
stu1.school = "YYY" # 修改对象的数据属性,其他对象以及类都不会发生变化
print(stu1.__dict__) # {'name': 'egon', 'age': 18, 'gender': 'male', 'school': 'YYY'}
print(stu1.school) # YYY
print(Student.school) # !!!
print(stu2.school) # !!!
print(stu3.school) # !!!
(3)类属性操作之绑定
类中定义的函数是为绑定给对象使用而准备的,绑定给哪个对象就由哪个对象来调用。对象.绑定方法()会把对象当作第一个参数传入(给self),若函数还有其他参数,应需继续传值。
类中的定义的函数属性,类可以调用,但类.函数()就是一个普通函数,没有自动传参的效果。
# 绑定的方法
print(Student.choose_course) # <function Student.choose_course at 0x0000023962238280>
print(stu1.choose_course) # <bound method Student.choose_course of <__main__.Student object at 0x0000023962225B50>>
stu1.choose_course() # choose_course(stu1) egon 正在选课
stu2.choose_course() # choose_course(stu2) 王三炮 正在选课
stu3.choose_course() # choose_course(stu3) 李大炮 正在选课
stu1.func(18,"male") # egon 18 male