1.面向对象前戏之人狗大战
"""推导步骤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
}
"""
如果想要定义多个人狗,需要多次编写上述字典,采用封装成函数的方式既可以提高效率,又方便随时调用
"""
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
p1 = create_person('max', 25, 'male', '刺客', 10000, 9999999)
print(p1)
p2 = create_person('kevin', 28, 'female', '淑女', 100, 800)
print(p2)
d1 = create_dog('小黑', '恶霸', 800, 900000)
d2 = create_dog('小白', '泰迪', 100, 800000)
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")}')
person_attack(p1, d1)
dog_attack(d2, p2)
person_attack(d1, p1)
dog_attack(p2, d2)
2.面向对象核心思路
"""
如何实现狗只能调用狗的攻击动作,人只能调用人的攻击动作?
"""
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)
dog1 = get_dog('小黑', '恶霸', 800, 900000)
person1.get('person_attack')(person1, dog1)
3.编程思想
1.面向过程编程:过程即流程,面向过程就是按照固定的流程解决问题,结局是固定的,也就是功能需求
eg:截止ATM为止,使用的几乎都是面向过程编程
注册功能 登录功能 转账功能(需要列举出每一步的流程,并且随着步骤的深入,问题的解决越来越简单)
解决思路:提出问题,然后制定出该问题的解决方案
2.面向对象编程
对象:容器、数据与功能的结合体(python中一切皆对象)
eg:游戏人物:亚索 劫 盲僧
面向对象编程有点类似于造物主,程序员只需要造出一个个对象,结局有无数个,对象将来会如何发展跟程序员没关系,也无法控制
"""
上述两种编程思想没有优劣之分 需要结合实际需求而定
如果需求是注册 登录 人脸识别肯定面向过程更合适
如果需求是游戏人物肯定是面向对象更合适
实际编程两种思想是彼此交融的 只不过占比不同
"""
4.面向对象之类与对象
对象:数据与功能的结合体 对象才是核心
类:多个对象相同数据和功能的结合体 类主要就是为了节省代码
"""
一个人 对象
一群人 人类(所有人相同的特征)
一条狗 对象
一群狗 犬类(所有狗相同的特征)
"""
现实中一般是先有对象再有类
程序中如果想要产生对象 必须要先定义出类
5.类与对象的创建
面向对象并不是一门新的技术 但是为了很好的一眼区分开 针对面向对象设计了新的语法格式,python中一定要有类 才能借助于类产生对象
1.类的语法结构:
class 类名:
'''代码注释'''
对象公共的数据
对象公共的功能
1.1 class是定义类的关键字
1.2 类名的命名与变量名几乎一致,类名的首字母推荐用大写
1.3 数据:变量名与数据值的绑定,功能或方法就是函数
2.类的定义与调用
class Student:
school_name = '清华大学'
def choice_course(self):
print('学生选课功能')
类在定义阶段就会执行类体代码,但是属于类的局部名称空间外界无法直接调用,只能在类的局部名称空间使用
2.1 查看类的局部名称空间中所有的名字
print(Student.__dict__)
2.2 拿到类的局部名称空间中的名字
print(Student.__dict__.get('school_name'))
print(Student.__dict__.get('choice_course'))
"""
上述过程太过繁琐,可以通过句点符统一访问
"""
print(Student.school_name)
print(Student.choice_course)
"""
类名点内部函数名只是查看函数名的内存地址,如果要执行的话必须加括号并且传入功能需要的参数,如果功能有返回值还会返回一个返回值,没有则会返回None
"""
print(Student.choice_course(111))
"""
类名加括号产生一个对象,并且每次都会产生一个全新的对象
"""
print(obj1)
obj1 = Student()
obj2 = Student()
obj3 = Student()
print(obj1, obj2, obj3)
"""
对象内部目前什么都没有
"""
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
"""
学生类目前产生了三个学生对象,本身为空,但是由于它们产生于一个类,他们可以通过点的方式拿到学生类的数据和功能
"""
print(obj1.school_name)
print(obj2.school_name)
print(obj3.school_name)
"""
通过类名点的方式修改类内部的名字,类内部的名字是公共的,当类内部名字修改后,所有对象拿到的名字都是修改后的名字并且相同
"""
Student.school_name = '上海交大'
print(obj1.school_name)
print(obj2.school_name)
print(obj3.school_name)
"""
数据和功能也可以成为属性,数据可能会被称为属性名
"""
6.对象独有的数据
class Student():
school_name = '清华大学'
def choice_course(self):
print('学生选课系统')
"""
推导流程1:
查看对象方式是通过 对象.__dict__ 来查看,可以看到返回的数据类型是一个字典,所以对象添加和修改数据的方式和字典类似。每个对象本身是空的,可以通过中括号的方式来添加独有的数据。如果中括号内是已有的数据运行结果是修改对象数据。
"""
obj1 = Student()
print(obj1.__dict__)
obj1.__dict__['name'] = 'max'
obj1.__dict__['age'] = 25
obj1.__dict__['hobby'] = 'soccer'
print(obj1.__dict__)
obj1.__dict__['age'] = 18
print(obj1.__dict__)
"""
推导流程2:
每个对象都可以通过 对象.名字的方式来查看对象独有的名字,注意此时pycharm中名字可能会标黄,但是可以正常运行
"""
print(obj1.name)
print(obj1.age)
print(obj1.hobby)
"""
推导流程3:给学生对象添加独有数据的函数只有学生对象有资格调用
"""
class Student():
school_name = '清华大学'
def init(obj, name, age, hobby):
obj.__dict__['name'] = name
obj.__dict__['age'] = age
obj.__dict__['hobby'] = hobby
def choice_course(self):
print('学生选课系统')
stu1 = Student()
Student.init(stu1, 'max', 25, 'soccer')
print(stu1.__dict__)
stu2 = Student()
Student.init(stu2, 'jason', 18, 'read')
print(stu2.__dict__)
"""
推导流程4:把init函数变量名变形成__init__,变形后python会自动触发执行两个操作:1.产生一个stu1空对象,2.把空对象和3个参数一起传到类里,并且给空对象添加独有的数据
"""
class Student():
school_name = '清华大学'
def __init__(obj, name, age, hobby):
obj.__dict__['name'] = name
obj.__dict__['age'] = age
obj.__dict__['hobby'] = hobby
def choice_course(self):
print('学生选课系统')
stu1 = Student('max', 25, 'soccer')
print(stu1.__dict__)
"""
操作流程5:把obj换成self,__dict__去掉,后面的字符串直接去掉引号(实际还是一个变量名),这样生成对象时还是只需传3个参数(self不算),并且直接通过点变量名的方式得到结果
"""
class Student():
school_name = '清华大学'
def __init__(self, name, age, hobby):
self.name = name
self.age = age
self.hobby = hobby
def choice_course(self):
print('学生选课系统')
stu1 = Student('max', 25, 'soccer')
print(stu1.name)
print(stu1.hobby)
"""
类当中都是对象共有的名字,但是每个对象也可以拥有自己单独的数据。在类中定义功能的时候把函数名替换成__init__,用self点的方式来赋值,底层原理是将传入功能的参数赋值给self点的变量名,self点的变量名其实是字字符串只不过在这里不需要加引号。通过类名括号内传参的方式将参数传递给功能,然后通过类名点的方式就可以拿到对象独有的数据。
"""
7.对象独有的功能
class Student:
school_name = '清华大学'
def __init__(self, name, age, hobby):
self.name = name
self.age = age
self.hobby = hobby
def choice_course(self):
print(f'学生{self.name}正在选课')
stu1 = Student('jason', 18, 'music')
stu2 = Student('kevin', 28, 'read')
1.直接在全局定义功能 该函数就不是学生对象独有的了
def eat():
print('吃东西')
stu1.eat = eat
print(stu1.__dict__)
stu1.eat()
2.只能将函数放在类中 但是类中的函数又是对象公共的
'''定义在类中的功能 默认就是绑定给对象使用的 谁来调谁就是主人公'''
Student.choice_course(123)
stu1.choice_course()
"""
对象修改数据值,当点的名字存在时,修改对应的键值对,不存在则新增键值对
"""
stu1.name = 'tony'
print(stu1.__dict__)
stu2.hobby = 'play game'
print(stu2.__dict__)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律