面向对象
【一】简介----》引入
-
将数据和功能进行绑定
-
不再是所有数据都可以调用任意的功能
-
上述将数据与功能整合到
-
可以理解为:可以理解我们写的面条版程序,一步接着做
#引入例题
# 定义专门用来描述人和狗的函数(最好单独编写)
def get_person(name, gender, age, t_type, attack_val, life_val):
data_dict = {
'name': name,
'gender': gender,
'age': age,
't_type': t_type,
'attack_val': attack_val,
'life_val': life_val
}
return data_dict
def get_dog(name, t_type, attack_val, life_val):
data_dict = {
'name': name,
't_type': t_type,
'attack_val': attack_val,
'life_val': life_val
}
return data_dict
p1 = get_person('dream', 'male', 18, '猛男', 800, 1000)
p2 = get_person('hope', 'female', 28, '淑女', 5, 100)
dog1 = get_dog('小黑', '松狮犬', 300, 500)
dog2 = get_dog('小白', '泰迪犬', 50, 200)
# 定义一个函数用来描述人和狗的攻击行为
def dog_attack(dog_obj, person_obj):
"""
:param dog_obj: 接收一条狗
:param person_obj: 接收一个人
"""
# 使用最简答的掉血逻辑 血量减去对方攻击力
print('当前人的血量是:%s' % person_obj.get('life_val'))
person_obj['life_val'] -= dog_obj.get('attack_val')
print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
dog_obj.get('name'), person_obj.get('name'), dog_obj.get('attack_val'), person_obj['life_val']))
def person_attack(person_obj, dog_obj):
"""
:param person_obj: 接收一个人
:param dog_obj: 接收一条狗
"""
print('当前狗的血量是:%s' % dog_obj.get('life_val'))
dog_obj['life_val'] -= person_obj.get('attack_val')
print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
person_obj.get('name'), dog_obj.get('name'), person_obj.get('attack_val'), dog_obj['life_val']))
# 狗咬人
dog_attack(dog2, p1)
print(p1)
# 人锤狗
person_attack(p2, dog1)
print(dog1)
'''人调用了狗的攻击动作'''
dog_attack(p1, dog1)
'''狗调用了人的攻击工作'''
person_attack(dog2, p2)
【二】面向对象和 面向过程
【1】面向过程
-
核心在于"过程"
-
将程序"流程化"
-
-
过程就像流水线,用来分步骤解决问题
-
过程指是解决问题的步骤,先干什么在干什么
-
面向对象的设计就好比精心设计好一条流水线,是一种机械式的思维方式。
【2】优点,缺点
-
优点
-
复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小步骤,去实现晓得步骤就会相对简单)
-
-
缺点
-
一套流水线或者流程就是用来解决一个问题。改一个组件,牵一发而动全身。
-
【3】面向对象
-
核心在于"对象"二字。
-
对象的终级奥秘就是将程序"整合"。
-
对象就是"容器",用来存放数据与功能
-
文字版理解
-
面向对象就相当于上帝,在上帝的视角,人是对象,动物是对象,石头是对象,水是对象,山是对象.....存在的可以扩充,不存在的可以创造。
-
-
可以这样理解面向对象就像我们要设计的校园模拟器,需要在校园中创造各种生活场景。
-
一个学校:下面有学生,老师,运动员等。。。
-
而每一个角色都会对应其具有的责任和功能
-
比如一个学生具有姓名、年龄、性别、所在班级等。
-
学生还有能做的活动,读书、写作、跑步、打篮球等。
-
比如一个老师可以教书、批改作业等。
-
比如运行员可以参加训练和比赛等。
-
-
-
可以理解为学校就是一个对象
【4】优缺点
-
优点
-
解决了程序的扩展性
-
对某一个对象单独修改,会立刻反映到整个体系中,比如对游戏中的人物和场景进行修改就会很容易,而且是立刻有成效。
-
-
缺点
-
编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。
-
无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。
-
【5】什么是程序
-
程序 = 数据 + 功能
-
编写程序的本质就是定义出一系列的数据,然后定义出一系列的功能来对数据进行操作。
【二】类
【1】什么是类
-
类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体
【2】定义类
-
只能描述共同特性,不同特性要对象自己描述
-
关键字class声明一个类(先定义了类才有对象)
-
定义类尽量用驼峰体(例如:User)
-
#定义类格式有的三种
1:class Student(object)
2:class Student()
3:class Student
#类名后面的 () 参数不写默认就是 object
#定义类的格式
class 类名:
类体代码
object:父类
1:class是定义类的关键字
2:类名类似于函数名,定义类尽量用驼峰体
3:类体代码就是存放对象公共数据和功能的地方
数据:变量名 = 变量值
功能:函数
#函数名()得到的是函数的返回值
# 如果你自己写了那就是你写的,如果没写就是 None
-
调用类的方法
#例子
变量名 = 类名()
print(变量名)#得到的是名称空间字典 例如:<__main__.Student object at 0x000001F2074B1340>
#想用类里面的属性和方法
print(变量名.属性)#前提是已经走了这一步:变量名 = 类名()
print(student.read())
【3】类的属性加扩展属性
【1】扩展属性
-
获取当前类的名字
-
对象名.
__name__
-
-
获取类中的文档字符串
-
对象名.
__doc__
-
-
获取类的父类
-
对象名.
__base__
-
-
获取类的所有父类
-
对象名.
__bases__
-
-
获取当前类的名称空间
-
变量名:
__dict__
-
-
获取类定义所在的模块名
-
变量名:
__module__
-
【2】类的定义
-
案例
class Student(object):
# 数据属性
school_name = "清华"
# 函数属性
def read(self):
age = 18
# self : 表示对象自己本身,
print(f"当前学校是 {self.school_name}")
student = Student()
print(student) # <__main__.Student object at 0x000001F2074B1340>
# 想用类里面的属性和方法
print(student.school_name)
print(student.read()) # None
【3】查看类的名称空间
【1】方法
-
__dict__
-
类.
__dict__
返回值是一个字典
【2】如何产生对象
-
类名加括号
【3】如何修改对象的属性
-
通过类的名称空间修改属性
-
类的名称空间不允许修改属性
class DreamStudent(object):
school = '梦想学城'
def read_books(self):
print('is reading books')
def write_nodes(self):
print('is write nodes')
def running(self):
print('is running')
obj1 = DreamStudent() # 目前对象没有自己独有的属性
obj2 = DreamStudent() # 目前对象没有自己独有的属性
print(obj1.__dict__) # 大白话就是给字典添加键值对 {}
print(obj2.__dict__) # 大白话就是给字典添加键值对 {}
'''方案1:逐步给对象添加独有的数据'''
obj1.__dict__['name'] = 'dream' # obj1.name = 'dream'
obj1.__dict__['age'] = 18 # obj1.age = 18
obj1.__dict__['gender'] = 'male' # obj1.gender = 'male'
obj2.__dict__['name'] = 'hope' # obj2.name = 'hope'
obj2.__dict__['age'] = 2 # obj2.age = 28
obj2.__dict__['gender'] = 'female' # obj2.gender = 'female'
print(obj1.__dict__,
obj2.__dict__) # {'name': 'dream', 'age': 18, 'gender': 'male'} {'name': 'hope', 'age': 2, 'gender': 'female'}
print(obj1.name) # dream
print(obj2.name) # hope
【4】批量修改属性
(0)修改方法
-
方式一:通过名称空间字典替换
-
student.
__dict__
['name'] = "dream"
-
-
方式二:通过对象.属性名=属性值替换
-
student_one.name = 'dream' student_one.age = 18 student_one.gender = 'male' student_two.name = 'opp' student_two.age = 19 student_two.gender = 'female'
-
(1)批量向对象中添加各自独有的属性值和属性名
-
init_obj(obj=student_one,name='dream',age=18,gender='male')
#Student():类名称
def init_obj(obj,name,age,gender):
obj.name = name
obj.age = age
obj.gender = gender
student_one = Student()
student_two = Student()
init_obj(obj=student_one,name='dream',age=18,gender='male')
init_obj(obj=student_two,name='opp',age=19,gender='female')
print(student_one.name)
print(student_two.name)
(2)在类内部初始化自己的参数
class Student(object):
# 数据属性
school_name = "清华"
def init_obj(self, name, age, gender):
# self 就是这个类的对象本身
self.name = name
self.age = age
self.gender = gender
# 函数属性
def read(self):
print(f"当前学校是 {self.school_name}")
print(f"当前学生姓名是 {self.name}")
print(f"当前学生年龄是 {self.age}")
print(f"当前学生性别是 {self.gender}")
student = Student()
# 'Student' object has no attribute 'name'
student.init_obj(name='dream',age=18,gender='male')
student.read()
【5】魔法方法值初始化方法 __init__
-
类中的
__init__
方法会在类产生对象的时候自己执行 -
类产生对象的具体步骤
-
先创建一个没有独有数据的空对象
-
将空对象和类括号内传入的数据一并交给
__init__
-
__init__
第一个参数就是对象本身 -
__init__
(obj,name,age,gender)
-
-
创建好的对象自动返回,给你提供这种方式能够减少代码的编写
-
-
针对括号内第一个形参self其实就是一个普通的变量名而已
-
只不过该变量名将来专门接收对象的 所以给它起了个固定的名字叫self
-
#案例
class Student(object):
# 数据属性
school_name = "清华"
def __init__(self, name, age, gender):
# self 就是这个类的对象本身
self.name = name
self.age = age
self.gender = gender
# 函数属性
def read(self):
print(f"当前学校是 {self.school_name}")
print(f"当前学生姓名是 {self.name}")
print(f"当前学生年龄是 {self.age}")
print(f"当前学生性别是 {self.gender}")
def write(self):
print(f"当前学生 :>>> {self.name} 可以写作业!")
# 初始化类得到对象
student = Student(name='dream', age=18, gender='male')
print(student.__dict__)
student.read()
student.write()
student_one = Student(name='opp', age=28, gender='female')
student_one.read()
student_one.write()
【6】属性查找顺序
-
由内向外
-
首先在自己的对象中查找
-
自己找不到就去父类里面找
-
如果父类里面找不到,就去基类里面找
-
如果基类里面也没有,就去 object 里面找
-
如果还是找不到则报错
-