一、人狗大战
1、需求
-
用代码模拟人、狗打架的小游戏
-
人和狗种类不同,因此双方的属性各不相同
推导一:
- 人和狗各有不同属性
- 使用字典方式储存属性较为方便,并可储存多种属性
# 1、在字典内储存‘人’属性
person = {
\'name\': \'阿拉蕾\',
\'age\': 18,
\'gender\': \'女\',
\'p_type\': \'战士\',
\'attack_val\': 8000,
\'life_val\': 99999999
}
# 2、在字典内储存‘狗’特有属性
dog1 = {
\'name\': \'小黑\',
\'d_type\': \'泰迪\',
\'attack_val\': 100,
\'life_val\': 8000
}
推导二:
- 按照上述方法,如果想要定义多个‘人’和‘狗’就需要反复设置多个字典,这样非常麻烦且费时
- 这时可推导出,想要快速、便捷的定义多个‘人’和‘狗’,那么我们可以把字典内的数据封装在函数内,利用传参的方式,这样可以较为方便的生成多个‘人’和‘狗’,只需要使用不同变量名调用函数时传不同的参数即可
# 1、封装‘人’属性函数
def create_person(name, age, gender, p_type, attack_val, life_val):
person_dict = {
\'name\': name,
\'age\': age,
\'gender\': gender,
\'p_type\': p_type,
\'attack_val\': attack_val,
\'life_val\': life_val
}
return person_dict
# 2、封装‘狗’属性的函数
def create_dog(name, d_type, attack_val, life_val):
dog_dict = {
\'name\': name,
\'d_type\': d_type,
\'attack_val\': attack_val,
\'life_val\': life_val
}
return dog_dict
# 3、生成多个‘人’和‘狗’
p1 = create_person(\'阿拉蕾\', 18, \'男\', \'战士\', 8000, 99999999)
p2 = create_person(\'小朵朵\', 28, \'女\', \'法师\', 100, 800)
d1 = create_dog(\'小黑\', \'泰迪\', 100, 8000)
d2 = create_dog(\'小白\', \'斗牛\', 100, 800000)
推导三:
- ‘人’和‘狗’就类似于各自不同种类的对象
- 说到这里,我们就应该明白,‘人’和‘狗’因为种类不同,所以双方的属性也各不相同,也就是说不同的对象,属性(数据)各不相同
- 当多个对象的属性生成后,我们就要开始定义彼此打架的动作(功能)
- 人打狗的动作
- 狗咬人的动作
# 1、人打狗的动作
def person_attack(person_dict, dog_dict):
print(f\"{person_dict.get(\'name\')}踢向{dog_dict.get(\'name\')}\")
dog_dict[\'life_val\'] -= person_dict.get(\'attack_val\')
print(f\"人踢了狗一脚 狗掉血:{person_dict.get(\'attack_val\')} 狗剩余血量:{dog_dict.get(\'life_val\')}\")
# 2、狗打人的动作
def dog_attack(dog_dict, person_dict):
print(f\"{dog_dict.get(\'name\')}向{person_dict.get(\'name\')}咬去\")
person_dict[\'life_val\'] -= dog_dict.get(\'attack_val\')
print(f\"狗咬了人一口 人掉血:{dog_dict.get(\'attack_val\')} 人剩余血量:{person_dict.get(\'life_val\')}\")
# 3、调用双方各自的函数,即可模拟出双方打架的动作
person_attack(p1, d1) # 人打狗
dog_attack(d2, p2) # 狗咬人
-------------------------------------------------------
阿拉蕾踢向小黑
人踢了狗一脚 狗掉血:8000 狗剩余血量:0
小白向小朵朵咬去
狗咬了人一口 人掉血:100 人剩余血量:700
2、核心思路
- ‘人’和‘狗’就是不同的对象
- 通过将不同的属性封装在不同的函数内,就可以通过相同的函数快速生成不同属性的对象
- ‘人’和‘狗’打架的方式就是对象的功能
- 人的打架方式是踢,狗的打架方式是咬,也就是说不同的类有着不同的功能,而相同的类就可以有着彼此相同的功能
需求:
- 以上我们完成了不同种类的打架方式,但是在python中,如果没有特别的限制,我们就可以把人攻击的数据传在狗攻击函数内,这样就会产生混乱,要如何实现下列需求
- ‘人’只能调用人的攻击方式
- ‘狗’只能调用狗的攻击方式
推导一:
\"\"\"推导步骤4:如何实现只有人只能调用的人的攻击动作 狗只能调用狗的攻击动作>>>:数据与功能的绑定\"\"\"
def get_person(name, age, gender, p_type, attack_val, life_val):
# 产生人的函数(功能)
def person_attack(person_dict, dog_dict):
print(f\"{person_dict.get(\'name\')}踢向{dog_dict.get(\'name\')}\")
dog_dict[\'life_val\'] -= person_dict.get(\'attack_val\')
print(f\"人踢了狗一脚 狗掉血:{person_dict.get(\'attack_val\')} 狗剩余血量:{dog_dict.get(\'life_val\')}\")
# 表示人的信息(数据)
person_dict = {
\'name\': name,
\'age\': age,
\'gender\': gender,
\'p_type\': p_type,
\'attack_val\': attack_val,
\'life_val\': life_val,
\'person_attack\': person_attack
}
return person_dict
def get_dog(name, d_type, attack_val, life_val):
def dog_attack(dog_dict, person_dict):
print(f\"{dog_dict.get(\'name\')}向{person_dict.get(\'name\')}咬去\")
person_dict[\'life_val\'] -= dog_dict.get(\'attack_val\')
print(f\"狗咬了人一口 人掉血:{dog_dict.get(\'attack_val\')} 人剩余血量:{person_dict.get(\'life_val\')}\")
dog_dict = {
\'name\': name,
\'d_type\': d_type,
\'attack_val\': attack_val,
\'life_val\': life_val,
\'dog_attack\': dog_attack
}
return dog_dict
person1 = get_person(\'jason\', 18, \'male\', \'猛男\', 8000, 99999999)
dog1 = get_dog(\'小黑\', \'恶霸\', 800, 900000)
person1.get(\'person_attack\')(person1, dog1)
结论:
- 通过上列代码,我们将人的专属攻击方式,封装在了人的类别内,实现了人专属的属性和功能,当人在调用自身类别,并传入符合条件的参数时,就可以生成一个人(对象)特有的属性(数据)和攻击方式(功能)
- 同上,我们也可将狗的数据和攻击方式封装在狗特有的函数内,当我们生成多条狗的时候,每条狗也就有了,狗(对象)特有的属性(数据)和攻击方式(功能)
人狗大战推导就是面对对象的核心思想:数据与功能的绑定!!
二、编程思想
引言:
-
面向对象是一种编程思想,用这种思想为指导设计的程序,把数据和对数据的操作封装在一起组成类,通过类来创建对象,通过对象之间的交互来实现程序的功能。
-
面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用
1、面向过程编程
- 面向过程即流程
- 在以上所学习的编程中,我们都是在按照固定的流程解决问题,制定一个结果,在奔向结果的过程中编写代码,以达到我们所需要的结果
- 需要例举出每一步流程 随着流程的深入 结果慢慢浮现
2、面向对象编程
- 对象即容器,数据与功能的结合体 (python中一切皆对象)
- 类似于开放式游戏,制定出游戏人物的(对象)
- 该人物未来会如何发展,全看用户如何控制,和我们程序员没有关系
- 类似于王者荣耀,玩家控制英雄走向
- 类似于王者荣耀,玩家控制英雄走向
上述两种编程思想没有优劣之分 需要结合实际需求而定
如果需求是注册 登录 人脸识别肯定面向过程更合适
如果需求是游戏人物肯定是面向对象更合适
实际编程两种思想是彼此交融的 只不过占比不同
三、面向对象
1、类与对象
对象:
- 数据与功能的结合体
- 是由类创建出来的一个具体存在,可以直接使用;由哪一个类创建出来的对象,该对象就具有在那一个类中定义的属性和方法
类:
- 多个对象相同数据和功能的结合体
- 是对一群具有相同特征或者行为的事物的一个统称,不能直接使用;特征被称为属性;行为被称为方法。
2、类与对象的创建
现实中一般是先有对象再有类
程序中如果想要产生对象 必须要先定义出类
1.语法结构
class 类名:
\'\'\'代码注释\'\'\'
对象公共的数据
对象公共的功能
1.class是定义类的关键字
2.类名几乎和变量名一致,使用的时候推荐类名的首字母大写
3.数据:
变量名与数据值的绑定
功能:
功能(方法)其实就是具有一定功能的函数
2.定义与调用
需求:
- 清华大学选课系统
\'\'\'
类在定义阶段就会执行类函数体代码
但类的函数体代码外界无法直接调用
\'\'\'
1、定义类
class Student:
# 对象公共的数据
school_name = \'清华大学\'
# 对象公共的功能
def choice_course(self):
print(\'学生选课功能\')
查看类的名称空间:
- 在面向对象中,类和对象访问数据或者功能,可以统一采用句点符
print(Student.__dict__)
# {\'__module__\': \'__main__\', \'school_name\': \'清华大学\', \'choice_course\': <function Student.choice_course at 0x0000018FCCCD5670>, \'__dict__\': <attribute \'__dict__\' of \'Student\' objects>, \'__weakref__\': <attribute \'__weakref__\' of \'Student\' objects>, \'__doc__\': None}
print(Student.__dict__.get(\'school_name\'))
# 清华大学
print(Student.__dict__ .get(\'choice_course\'))
# <function Student.choice_course at 0x000001417B975670>
类的调用:
- 类加括号就会产生对象,并且每调用一次就会产生一个全新的对象
- 变量名obj接收类名加括号之后的返回值(结果)
1、调用对象
obj1 = Student()
# <__main__.Student object at 0x000001992C2759D0>
obj2 = Student()
# <__main__.Student object at 0x000001992C278E50>
obj3 = Student()
# <__main__.Student object at 0x000001992C278E20>
\'\'\'
三个变量名的地址各不相同,产生三个对象
\'\'\'
2、查看对象内部数据
print(obj1.__dict__,
obj2.__dict__,
obj3.__dict__)
# {} {} {}
\'\'\'
三个对象各自内部都为空
\'\'\'
3、调用对象共同数据
print(obj1.school_name)
# 清华大学
print(obj2.school_name)
# 清华大学
print(obj3.school_name)
# 清华大学
\'\'\'
同一类产生的对象,都可使用类内部公用数据值
\'\'\'
数据和功能可称统称为属性:
数据>>>属性名
功能>>>方法
3、对象独有数据
在上述使用类产生对象时,我们可以看出产生的对象并没有自己特有的数据,针对如何给对象手动添加独有数据,python提供了多种方式,其中前4种方式主要为推导第五种方式而来,我们只需简单了解即可,在日后我们重点使用的是第五种方式
第一种:
- 通过__ dict __ 加中括号的方式
obj1.__dict__[\'name\'] = \'jason\'
obj1.__dict__[\'age\'] = 18
obj1.__dict__[\'hobby\'] = \'study\'
第二种:
- 将对象独有的数据提前封装成函数,在后续添加的时候,通过传参的方式进行添加
def init(ojb,name,age,hobby)
oib.__dict__[\'name\'] = name
obj.__dict__[\'age\'] = age
obj.__dict__[\'hobby\'] = hobby
init(ojb1.\'kangkang\', 18, \'read\')
init(ojb2, \'zhangzhang\', 28, \'ball\')
第三种:
- 将封装数据的函数放在类的内部,只有相同类的对象才有资格使用
class Student:
# 对象公用的数据
school_name = \'清华大学\'
# 专门给学生添加独有数据的功能
def init(ojb, name, age, hobby):
oib.__dict__[\'name\'] = name
obj.__dict__[\'age\'] = age
obj.__dict__[\'hobby\'] = hobby
# 对象公共的功能
def choice_course(self):
print(\'学生选课功能\')
stu1 = Student()
Student.init(stu1, \'kangkang\', 18 , \'read\')
Student.init(stu2, \'zhangzhang\', 28 , \'ball\')
第四种:
- 将封装独有功能的函数名替换成__ init __ 这种方式,在我们给对象添加独有功能时,可自动触发
class Student:
# 对象公用的数据
school_name = \'清华大学\'
# 专门给学生添加独有数据的功能
def __init__(ojb, name, age, hobby):
oib.__dict__[\'name\'] = name
obj.__dict__[\'age\'] = age
obj.__dict__[\'hobby\'] = hobby
# 对象公共的功能
def choice_course(self):
print(\'学生选课功能\')
stu1 = Student()
Stu1.Student(\'kangkang\', 18, \'read\')
Stu2.Student(\'zhangzhang\', 28, \'ball\')
第五种:
-
封装独有数据的函数体的第一个参数位置修改为self
-
在使用类产生对象时直接在类的括号内填入独有数据
-
这种方式是我们日后使用类产生独有数据对象的主要方式
class Student:
# 对象公用的数据
school_name = \'清华大学\'
# 专门给学生添加独有数据的功能
def __init__(self, name, age, hobby):
oib.__dict__[\'name\'] = name
obj.__dict__[\'age\'] = age
obj.__dict__[\'hobby\'] = hobby
# 对象公共的功能
def choice_course(self):
print(\'学生选课功能\')
stu1 = Student(\'kangkang\', 18, \'read\')
stu1 = Student(\'zhangzhang\', 18, \'ball\')
4、对象独有功能
上述学习了如何给相同类对象添加独有数据的方式,下面我们要学习如何给对象添加独有功能
思考:
- 1、直接将功能函数体代码定义在全局名称空间种,那么该功能函数就不对象独有的功能
- 2、将功能函数体代码放在类中,但是类中的函数体功能,只要是此类产生的对象都可调用
解决方法:
- 定义在类中的功能,默认就是给类产生的对象使用的,只要是此类产生的对象都可以使用
- 需要在功能函数形参数内填入self,之后只需要用类名’点‘函数名的方式,函数参数内填入调用对象名,就可直接使用该功能
class Student:
# 对象公用的数据
school_name = \'清华大学\'
# 专门给学生添加独有数据的功能
def __init__(self, name, age, hobby):
oib.__dict__[\'name\'] = name
obj.__dict__[\'age\'] = age
obj.__dict__[\'hobby\'] = hobby
# 对象公共的功能
def choice_course(self):
print(\'学生选课功能\')
stu1 = Student()
Student.choice_course(stu1)
5、补充知识
1、对象数据值修改
# 只需要使用对象‘点’的数据绑定的变量名的方式重新赋值即可
stu1.name = \'zhaozhao\'
# 当名字不存在的情况下,将直接新增数据
stu1.paw = 123
来源:https://www.cnblogs.com/kangssssh/p/16852630.html
本站部分图文来源于网络,如有侵权请联系删除。