面向对象前戏之人狗大战

# 编写代码简单的实现人打狗 狗咬人的小游戏(剧情需要)
"""推导步骤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}

python学习第五周总结的更多相关文章

  1. python学习第五次笔记

    python学习第五次笔记 列表的缺点 1.列表可以存储大量的数据类型,但是如果数据量大的话,他的查询速度比较慢. 2.列表只能按照顺序存储,数据与数据之间关联性不强 数据类型划分 数据类型:可变数据 ...

  2. Python学习第五堂课

    Python学习第五堂课推荐电影:华尔街之狼 被拯救的姜哥 阿甘正传 辛德勒的名单 肖申克的救赎 上帝之城 焦土之城 绝美之城 #上节内容: 变量 if else 注释 # ""& ...

  3. 201671010140. 2016-2017-2 《Java程序设计》java学习第五周

    java学习第五周心得体会        本周,是Java学习第五周,随着时间推移,随着课本内容的推进,我们接触到的程序也开始变得越来越复杂,不再是二三章那些用来练手的小程序了,这一点,在我们的例题运 ...

  4. python学习笔记第二周

    目录 一.基础概念 1.模块 1)os模块 2)sys模块 2.pyc文件 3.数据类型 1)数字 2)布尔值 3)字符串 4.数据运算 5.运算符 6.赋值运算 7.逻辑运算 8.成员运算 9.身份 ...

  5. python学习笔记五 模块上(基础篇)

    模块学习 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...

  6. Python学习笔记五

    一. 递归 递归函数: def a (): print ("from b") b() def b(): print("from a ") a() a() 递推和 ...

  7. Python学习笔记五:错误与异常

    一:常见异常与错误 BaseException 所有异常的基类SystemExit 解释器请求退出KeyboardInterrupt 用户中断执行(通常是输入^C)Exception 常规错误的基类S ...

  8. Python 学习 第五篇:语句和语法

    Python程序是语句构成的,语句包含表达式,表达式嵌套在语句中,包含变量和常量,用于处理对象.Python的语法实质上是由表达式.语句和代码块构成的.语句是由表达式构成的,代码块是由多个语句构成的复 ...

  9. Python学习(五)函数 —— 内置函数 lambda filter map reduce

    Python 内置函数 lambda.filter.map.reduce Python 内置了一些比较特殊且实用的函数,使用这些能使你的代码简洁而易读. 下面对 Python 的 lambda.fil ...

  10. python学习笔记(五):装饰器、生成器、内置函数、json

    一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...

随机推荐

  1. JAVA-注解之 TODO、FIXME、XXX

    TODO.FIXME.XXX    //TODO : 表示待实现的功能    //FIXME: 代码存在Bug,不能Run或运行结果不正确,需要修复    //XXX  : 勉强可以工作,但是实现的方 ...

  2. 思维分析逻辑 1 DAY

    数据分析原则:坚决不做提数机器. 数据分析工作模块 日报 了解业务现状 提升数据敏感性 数据波动解释 周报 了解数据的短期趋势 版本迭代分析 为结论型报告背书 月报 梳理业务的流程 为决策提供部分建议 ...

  3. MYSQL5.7 保姆级安装教程

    现在要是说mysql是什么东西,就不礼貌了 虽然有的同学没有进行系统的深入学习,但应该也有个基本概念 [不了解也没关系,后续会进行mysql专栏讲解]简单来说,存储数据的 学习mysql,就要先安装它 ...

  4. 【CDH数仓】Day01:概念、环境搭建、CDH数仓搭建、用户行为数仓搭建

    一.数仓之Cloudera Manager 1.CM简介 拥有集群自动化安装.中心化管理.集群监控.报警功能的一个工具 快速安装,快速运维,提高集群的效率 CM架构 2.阿里云服务器准备 注册账号 购 ...

  5. Vue3 企业级优雅实战 - 组件库框架 - 8 搭建组件库 cli

    前面的文章分享了组件库的开发.example.组件库文档,本文分享组件库 cli 开发. 1 为什么要开发组件库 cli 回顾一个新组件的完整开发步骤: 1 在 packages 目录下创建组件目录 ...

  6. L1-064 估值一亿的AI核心代码 (20分)

    L1-064 估值一亿的AI核心代码 (20分) 以上图片来自新浪微博. 本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是: 无论用户说什么,首先把对方说的话在一行中原样打印出来: 消除 ...

  7. 论文解读(PCL)《Probabilistic Contrastive Learning for Domain Adaptation》

    论文信息 论文标题:Probabilistic Contrastive Learning for Domain Adaptation论文作者:Junjie Li, Yixin Zhang, Zilei ...

  8. 瞧瞧别人家的API接口,那叫一个优雅

    前言 在实际工作中,我们需要经常跟第三方平台打交道,可能会对接第三方平台API接口,或者提供API接口给第三方平台调用. 那么问题来了,如果设计一个优雅的API接口,能够满足:安全性.可重复调用.稳定 ...

  9. DataTables实现按分组小计

    效果图:

  10. VC实例和VM实例的区别!!!

    1.内置关系是什么 VueComponent.prototype.__proto__ === Vue.prototype 2.为什么要有这个关系 让组件实例对象可以访问到 Vue原型上的属性.方法.