面向对象基础、对象的属性
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
}
"""
如果想要定义多个人狗,需要多次编写上述字典,采用封装成函数的方式既可以提高效率,又方便随时调用
"""
# 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
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) # 调用函数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
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')) # <function Student.choice_course at 0x000001CACCDE17B8>
"""
上述过程太过繁琐,可以通过句点符统一访问
"""
print(Student.school_name) # 清华大学
print(Student.choice_course) # <function Student.choice_course at 0x00000268FC1217B8>
"""
类名加括号产生一个对象,并且每次都会产生一个全新的对象
"""
print(obj1) # <__main__.Student object at 0x000001EA2CAD0748>
obj1 = Student()
obj2 = Student()
obj3 = Student()
print(obj1, obj2, obj3) # <__main__.Student object at 0x00000219EDE1B208> <__main__.Student object at 0x00000219EDE1B128> <__main__.Student object at 0x00000219EDE1B0B8>
"""
对象内部目前什么都没有
"""
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__) # {'name': 'max', 'age': 25, 'hobby': 'soccer'}
obj1.__dict__['age'] = 18
print(obj1.__dict__) # {'name': '
"""
推导流程2:
每个对象都可以通过 对象.名字的方式来查看对象独有的名字,注意此时pycharm中名字可能会标黄,但是可以正常运行
"""
print(obj1.name) # max
print(obj1.age) # 18
print(obj1.hobby) # soccer
"""
推导流程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__) # {'name': 'max', 'age': 25, 'hobby': 'soccer'}
stu2 = Student()
Student.init(stu2, 'jason', 18, 'read')
print(stu2.__dict__) # {'name': 'jason', 'age': 18, 'hobby': 'read'}
"""
推导流程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__) # {'name': 'max', 'age': 25, 'hobby': 'soccer'}
"""
操作流程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) # max
print(stu1.hobby) # soccer
7.对象独有的功能
class Student:
# 对象公共的数据
school_name = '清华大学'
# 专门给学生添加独有数据的功能 类产生对象的过程中自动触发
def __init__(self, name, age, hobby):
self.name = name # self.__dict__['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() # choice_course(stu1) 对象调用会自动将对象当做第一个参数传入。如果函数内有两个参数需要再传一个。
"""
对象修改数据值,当点的名字存在时,修改对应的键值对,不存在则新增键值对
"""
stu1.name = 'tony'
print(stu1.__dict__) # {'name': 'tony', 'age': 25, 'hobby': 'soccer'}
stu2.hobby = 'play game'
print(stu2.__dict__) # {'name': 'jason', 'age': 18, 'hobby': 'play game'}
原文地址:http://www.cnblogs.com/zkz0206/p/16852192.html
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。