# 编写代码简单的实现人打狗 狗咬人的小游戏(剧情需要)
"""推导步骤1:代码定义出人和狗"""
person1 = {
'name': 'jason',
'age': 18,
'gender': 'male',
'p_type': '猛男',
'attack_val': 8000,
'life_val': 99999999
}
person2 = {
'name': 'kevin',
'age': 28,
'gender': 'female',
'p_type': '淑女',
'attack_val': 1,
'life_val': 100
}
dog1 = {
'name': '小黑',
'd_type': '泰迪',
'attack_val': 100,
'life_val': 8000
}
dog2 = {
'name': '小白',
'd_type': '恶霸',
'attack_val': 2,
'life_val': 80000
}
"""
如果想要定义多个人狗,需要多次编写上述字典,采用封装成函数的方式既可以提高效率,又方便随时调用
"""
# 1.定义出人狗的函数
def create_person(name, age, gender, p_type, attack_val, life_cal):
person_dict = {
'name': name,
'age': age,
'gender': gender,
'p_type': p_type,
'attack_val': attack_val,
'life_val': life_cal
}
return person_dict
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
# 2.调用函数,传参,接受函数体代码的返回值
p1 = create_person('max', 25, 'male', '刺客', 10000, 9999999)
print(p1) # 生成字典然后返回,p1:{'name': 'max', 'age': 25, 'gender': 'male', 'p_type': '刺客', 'attack_val': 10000, 'life_cal': 9999999}
p2 = create_person('kevin', 28, 'female', '淑女', 100, 800)
print(p2) # {'name': 'kevin', 'age': 28, 'gender': 'female', 'p_type': '淑女', 'attack_val': 100, 'life_cal': 800}
d1 = create_dog('小黑', '恶霸', 800, 900000) # d1:{'name': '小黑', 'd_type': '恶霸', 'attack_val': 800, 'life_val': 900000}
d2 = create_dog('小白', '泰迪', 100, 800000) # d2:{'name': '小白', 'd_type': '泰迪', 'attack_val': 100, 'life_val': 800000}
# 3.定义出人打狗、狗咬人的动作
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")}')
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")}')
# 4.正确传参:通过刚才d1、d2、p1、p2通过定义字典函数返回的返回值,把相应字典当做参数传入
person_attack(p1, d1) # 人max准备揍狗小黑 人揍了狗一拳,狗掉血10000,剩余血量890000
dog_attack(d2, p2) # 狗小白准备咬人kevin 狗咬了人一口,人掉血100,人剩余血量700
# 5.错误传参:将人的参数传给了狗,狗的参数传给了人。因此得出采用传参的方式极易将犯错误的参数传递给函数
person_attack(d1, p1) # 人小黑准备揍狗max 人揍了狗一拳,狗掉血800,剩余血量9999199
dog_attack(p2, d2) # 狗kevin准备咬人小白 狗咬了人一口,人掉血100,人剩余血量799900
"""
如何实现狗只能调用狗的攻击动作,人只能调用人的攻击动作?
"""
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('max', 25, 'male', '猛男', 1000, 80000) # 调用函数get_person并传参,此时person1 = person_dict
dog1 = get_dog('小黑', '恶霸', 800, 900000) # 调用函数get_dog并传参,此时dog1 = dog_dict
person1.get('person_attack')(person1, dog1) # 相当于调用了函数person_attack(person1, dog1),并传入字典person_dict、dog_dict
1.面向过程编程:过程即流程,面向过程就是按照固定的流程解决问题,结局是固定的,也就是功能需求
eg:注册功能、登录功能、转账功能(需要留举出每一步的流程,并且随着步骤的深入,问题的解决越来越简单)
结局思路:提出问题,然后指定出解决问题的方案
2.面向对象编程:类似造物主,程序员只需要造出一个个对象,结局有无数个,对象将来会如何发展和程序员没有关系,也无法控制
"""
上述两种编程思想没有优劣之分,需要结合实际需求而定
如果需求是注册、登陆、人脸识别肯定面相好过程更合适
如果需求是游戏人物name面向对象更合适
实际编程两种思想是彼此交融的,只不过占比不同
"""
对象:数据与功能的结合体,对象才是核心
类:多个对象相同数据和功能的结合体,类主要功能是为了节省代码
"""
一个人:对象
一群人:人类(所有人相同的特征)
"""
现实中一般是先有对象再有类,程序中如果想要产生对象,必须要先定义出类
面向对象并不是一门新的技术,但是为了更好地适应功能并且便于区分,针对面向对象设计了新的语法格式,python中一定要有类,才能借助于类产生对象
1.类的语法结构:
class 类名:
'''代码注释'''
对象公共的数据
对象公共的功能
1.1 class是定义类的关键字
1.2类名的命名与变量名几乎一致,类名的首字母推荐用大写
1.3数据:变量名与数据值的绑定;功能或方法就是函数
2.类的定义与调用
# 需求:选课系统
#定义类
class Student:
# 对象公共的数据:
school_name = '清华大学'
# 对象公共的功能
def choice_course(self):
print('学生选课功能')
类在定义阶段就会执行类体代码,但是类的局部名称空间外无法直接调用,只能在类的局部名称空间使用
2.1:查看类的局部名称空间中所特有的名字:类名.dict__
print(Student.__dict__)
2.2:拿到类的局部名称空间中的名字:类名.dict__.get('类中的名字')
'''类中的名字要加引号'''
print(Student.__dict__.get('name'))
2.3上述过程太过繁琐,可以直接用类名点名字的方式拿到类中的名字
print(Student.name) # jason
print(Student.choice_course) # <function Student.choice_course at 0x000001DD04C7E730>
print(Student.choice_course(111)) # 选课系统 None
2.4类名加括号可以产生一个对象,并且每次都会产生全新的对象
obj1 = Student()
obj2 = Student()
obj3 = Student()
print(obj1, obj2, obj3) # <__main__.Student object at 0x000001F81E91B0B8> <__main__.Student object at 0x000001F81E9DC588> <__main__.Student object at 0x000001F81E9DC940>
2.5类名中本身什么都没有,类Student目前产生了三个对象,本身为空,由于它们产生于一个类,它们可以拿到类Student的数据和功能
print(obj1.name) # jason
print(obj2.name) # jason
print(obj3.name) # jason
2.6通过类名点的方式修改类内部的名字,类内部的名字是公共的,当类内部的名字修改后,所有对象拿到的名字都是修改后的名字
Student.name = 'max'
print(obj1.name) # max
print(obj2.name) # max
print(obj3.name) # max
"""
数据和功能也可以称为属性,数据可能会被称为属性名
"""
类当中都是对象共有的名字,但是每个对象也可以拥有自己单独的数据。在类中定义功能的时候把函数名替换成__init__,用self点的方式来赋值,底层原理是将传入功能的参数赋值给self点的变量名,self点的变量名其实是字字符串只不过在这里不需要加引号。通过类名括号内传参的方式将参数传递给功能,然后通过类名点的方式就可以拿到对象独有的数据。
class Student:
school_name = '清华大学'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
stu1 = Student('max', 25, 'male')
print(stu1.name) # max
print(stu1.gender) # male
stu2 = Student('jason', 18, 'male')
print(stu2.__dict__) # {'name': 'jason', 'age': 18, 'gender': 'male'}
print(stu2.name) # jason
定义在类中的功能 默认就是绑定给对象使用的 谁来调谁就是主人公。类调用功能需要手动传参,而对象调用不需要传参,因为对象会将自身当做第一个参数传入功能。如果功能需要多个参数的话,对象调用功能需将第一个参数以外的参数手动传入
class Student:
def choice_course(self):
print('选课系统')
Student.choice_course(111) # 选课系统
stu1 = Student()
stu1.choice_course() # 选课系统
class Student:
def choice_course(self, name):
print('选课系统')
stu1 = Student()
stu1.choice_course('max') # 选课系统
1.在类中定义的函数(功能有多重属性)
"""
类名加括号会产生一个对象,对象用点函数名的方式不用传参,因为对象对被当做第一个参数自动传入,类名点函数名需要传参
"""
class Group:
s = 'from Group'
def func1(self):
print('from func1')
gro = Group()
gro.func1() # from func1
Group.func1(111) # from func1
2.被@classmethond修饰的函数默认绑定给类,类会将自身当做第一个参数传入,所以类调用函数不需要传参。对象调永也不需要传参
class Group:
s = 'from group'
@classmethod
def func1(cls):
print('from func1')
Group.func1() # from func1
gro = Group()
gro.func1() # from func1
3.被@staticmethod修饰的函数就是一个普普通通的函数,不管是类还是对象,调用内部的函数都需要传参
class Group:
@staticmethod
def func1(name):
print('from func1')
Group.func1('max') # from func1
gro = Group
gro.func1('max') # from func1
"""
1.面向对象的三大特征:封装、继承、多态
2.三者中继承最为核心
3.封装和多态略为抽象
"""
1.继承的含义:
在现实生活中表示人与人之间资源的从属关系
在编程世界里表示类与类之间资源的从属关系
2.继承的目的:
和现实生活中类似,编程中继承表示不同类之间资源从属关系,比如B类继承A类,那么B类可以共享A类中的数据和功能
3.继承实操:
3.1在定义类的时候类名后面可以加括号填写其他类名,表示继承该类名
class Student:
name = 'max'
class Teacher(Student):
pass
tea1 = Teacher()
print(tea1.name) # max
3.2在python中支持多继承,括号内填写多个类名,用逗号隔开
class A1:
name = 'max'
class A2:
age = 25
class A3:
gender = 'male'
class A4(A1, A2, A3):
pass
a = A4()
print(a.name, a.age, a.gender) # max 25 male
"""
1.继承其他类的类,我们称之为子类、派生类
2.被继承的类,我们称之为父类
"""
"""
通过对象和类的概念引出继承的本质:
对象:数据与功能的结合体
类:多个对象相同数据和功能的结合体
父类:多个类(子类)相同数据和功能的结合体
类与父类本质都是为了节省代码
"""
继承本质应该分为两部分:
抽象:将多个类相同的东西抽出去形成一个新的类
继承:将多个类继承刚刚抽取出来的新的类
1.不继承情况下名字的查找顺序:
1.1:当对象中有名字,首先从对象的名称空间查找
class A1:
name = 'jason'
a = A1()
print(a.__dict__) # {}
a.name = 'max'
print(a.name) # max
"""
因为查找的是对象的名字,所以每次查找的名字之前一定要先生成一个对象,并且用对象名点名字
"""
1.2当对象中没有名字时,去类中查找
class Student:
name = 'max'
stu1 = Student()
print(stu1.name) # max
1.3如果类中也没有,那么直接报错
class Student:
name = 'max'
stu1 = Student()
print(stu1.age) # 报错
"""
对象名称空间>>>:类(没有即报错)
"""
2.单继承情况下名字查找顺序:
2.1:对象名称空间有要找的名字时,直接去对象名称空间找
class A1:
name = 'from A1'
class A2(A1):
pass
a2 = A2()
a2.name = 'from a2'
print(a2.name) # from a2
2.2当对象名称空间中没有时,去产生对象的类名称空间中查找
class A1:
name = 'from A1'
class A2(A1):
name = 'from A2'
a2 = A2()
print(a2.name) # from A2
2.3当类名称空间中没有时,去父类名称空间中查找
class A1:
name = 'from A1'
class A2(A1):
pass
a2 = A2()
print(a2.name) # from A1
"""
对象名称空间>>>产生对象的类名称空间>>>父类(没有即报错)
"""
3.多继承情况下名字查找顺序:
3.1对象名称空间中有时首先找对象名称空间
class A:
name = 'from A'
class B:
name = 'from B'
class C:
name = 'from C'
class S(A, B, C):
name = 'from S'
obj = S()
obj.name = 'obj名称空间中的name'
print(obj.name) # obj名称空间中的name
3.2对象名称空间中没有时,从产生它的类名称空间中查找
class A:
name = 'from A'
class B:
name = 'from B'
class C:
name = 'from C'
class S(A, B, C):
name = 'from S'
obj = S()
print(obj.name) # from S
3.3类名称空间没有时直接从父类名称空间中查找(从左往右)
class A:
name = 'from A'
class B:
name = 'from B'
class C:
name = 'from C'
class S(A, B, C):
pass
obj = S()
print(obj.name) # from A
4.非菱形继承
class G:
name = 'from G'
class A:
name = 'from A'
class B:
name = 'from B'
class C:
name = 'from C'
class D(A):
name = 'from D'
class E(B):
name = 'from E'
class F(C):
name = 'from F'
class S1(D, E, F):
pass
obj = S1()
print(obj.name)
"""
非菱形继承查找顺序首先查找对象名称空间,在查找产生对象的类名称空间,如果没有继续查找父类名称空间,父类名称空间查找顺序为从左往右,从下往上,也可以用print(s1.mro)方法来查看查找顺序,上述题目在父类D名称空间可以找到name,如果找不到再去其父类A中查找。
"""
5.菱形继承
class G:
name = 'from G'
pass
class A(G):
name = 'from A'
pass
class B(G):
name = 'from B'
pass
class C(G):
name = 'from C'
pass
class D(A):
name = 'from D'
pass
class E(B):
name = 'from E'
pass
class F(C):
name = 'from F'
pass
class S1(D,E,F):
pass
obj = S1()
print(obj.name)
"""
菱形查找顺序为先从对象你名称空间中查找,再到类名称空间,再到父类名称空间。父类名称空间查找顺序从左到右,走道菱形交汇点之前停止,直到所有的类都找完,再找交汇点的类。
"""
"""
经典类:不继承object或其子类的类
新式类:继承object或其子类的类
在python2中有经典类和新式类
在python3中只有新式类(所有类都默认继承objecr)
"""
class Student(object):pass
为了更好地兼容python2,以后我们在定义类的时候,如果没有其他明确的父类,也可以直接在括号内加上object
1.子类基于父类做扩展:Student的父类为Person,说明在类Student中可以用到类Person中的名字,但是类Student还想扩展一个名字level,此时可以用到关键字super().__init__(父类所有的名字),然后再扩展新增自己的名字
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Person):
def __init__(self, name, age, gender, level):
super().__init__(name, age, gender)
self.level = level
stu1 = Student('max', 25, 'male', 2)
print(stu1.__dict__) # {'name': 'max', 'age': 25, 'gender': 'male', 'level': 2}
print(stu1.name) # max
class Teacher(Person):
def __init__(self, name, age, gender, grade):
super().__init__(name, age, gender)
self.grade = grade
tea1 = Teacher('jason', 18, 'male', 9)
print(tea1.__dict__) # {'name': 'jason', 'age': 18, 'gender': 'male', 'grade': 9}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章