python学习第五周总结
面向对象前戏之人狗大战
# 编写代码简单的实现人打狗 狗咬人的小游戏(剧情需要)
"""推导步骤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学习第五周总结的更多相关文章
- python学习第五次笔记
python学习第五次笔记 列表的缺点 1.列表可以存储大量的数据类型,但是如果数据量大的话,他的查询速度比较慢. 2.列表只能按照顺序存储,数据与数据之间关联性不强 数据类型划分 数据类型:可变数据 ...
- Python学习第五堂课
Python学习第五堂课推荐电影:华尔街之狼 被拯救的姜哥 阿甘正传 辛德勒的名单 肖申克的救赎 上帝之城 焦土之城 绝美之城 #上节内容: 变量 if else 注释 # ""& ...
- 201671010140. 2016-2017-2 《Java程序设计》java学习第五周
java学习第五周心得体会 本周,是Java学习第五周,随着时间推移,随着课本内容的推进,我们接触到的程序也开始变得越来越复杂,不再是二三章那些用来练手的小程序了,这一点,在我们的例题运 ...
- python学习笔记第二周
目录 一.基础概念 1.模块 1)os模块 2)sys模块 2.pyc文件 3.数据类型 1)数字 2)布尔值 3)字符串 4.数据运算 5.运算符 6.赋值运算 7.逻辑运算 8.成员运算 9.身份 ...
- python学习笔记五 模块上(基础篇)
模块学习 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...
- Python学习笔记五
一. 递归 递归函数: def a (): print ("from b") b() def b(): print("from a ") a() a() 递推和 ...
- Python学习笔记五:错误与异常
一:常见异常与错误 BaseException 所有异常的基类SystemExit 解释器请求退出KeyboardInterrupt 用户中断执行(通常是输入^C)Exception 常规错误的基类S ...
- Python 学习 第五篇:语句和语法
Python程序是语句构成的,语句包含表达式,表达式嵌套在语句中,包含变量和常量,用于处理对象.Python的语法实质上是由表达式.语句和代码块构成的.语句是由表达式构成的,代码块是由多个语句构成的复 ...
- Python学习(五)函数 —— 内置函数 lambda filter map reduce
Python 内置函数 lambda.filter.map.reduce Python 内置了一些比较特殊且实用的函数,使用这些能使你的代码简洁而易读. 下面对 Python 的 lambda.fil ...
- python学习笔记(五):装饰器、生成器、内置函数、json
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...
随机推荐
- [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)
[数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构) C#中的链表(源码) 可空类 ...
- 从0到1搭建redis6.0.7
redis集群搭建 一.安装redis 源码安装: 1.下载源码包: wget http://download.redis.io/releases/redis-6.0.7.tar.gz 2.解压到指定 ...
- Spring Boot 中使用 tkMapper
说明:基于 MyBatis 有很多第三方功能插件,这些插件可以完成数据操作方法的封装.数据库逆向工程的生成等. tkMapper 和 MyBatis-plus 都是基于 MyBatis 提供的第三方插 ...
- Oracle 表空间常用操作
aliases: [Oracle表空间] tags: [数据库,Oracle,Blog] summary: [Oracle表空间常用操作,包括查询.分析.扩容.删除.优化等] date: ...
- kubeedge架构与核心设计---https://bbs.huaweicloud.com/webinar/100009
今天是kubeedge的第一节课,今天主要带大家回顾一下云原生和边缘计算的发展历程 然后我们会重点介绍一下kubeedge这个项目,他的设计背景和核心理念与我们整体的架构 首先是我们来简单回归一下云原 ...
- vivo霍金实验平台设计与实践-平台产品系列02
vivo 互联网平台产品研发团队 - Bao Dawei 本篇介绍了vivo霍金实验平台的系统架构以及业务发展过程中遇到的问题以及对应的解决方案. <平台产品>系列文章: 1.vivo平台 ...
- 大前端系统学-了解html
标签: 使用尖括号包起来的就是标签,例如我们看到的 <html></html> 一对标签 <head> 开始标签 </head> 结束标签 < ...
- 关于js更改编码问题
前言 前几天调试喜马拉雅的js加密算法,找到固定一段加密算法后调试,发现结果与实际不一致,后来发现是js显示的编码不一致,而我用的密钥是直接通过 chrome控制台复制下来的,这就导致最后结果不一致. ...
- Clickhouse表引擎之MergeTree
1.概述 在Clickhouse中有多种表引擎,不同的表引擎拥有不同的功能,它直接决定了数据如何读写.是否能够并发读写.是否支持索引.数据是否可备份等等.本篇博客笔者将为大家介绍Clickhouse中 ...
- “XZ”格式文件解压
1.下载xz 官网:https://tukaani.org/xz/ 例:wget https://nchc.dl.sourceforge.net/project/lzmautils/xz-5.2.6. ...