学习Python第三周总结
2021/8/7 12:05:54
本文主要是介绍学习Python第三周总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
学习Python第三周总结
一、函数和模块
1.1 函数的定义
Python中的函数的自变量称为函数的参数,而因变量称为函数的返回值
在Python中可以使用def
关键字来定义函数,命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,就是我们刚才说到的函数的自变量,而函数执行完成后我们会通过return
关键字来返回函数的执行结果,就是我们刚才说的函数的因变量。一个函数要执行的代码块(要做的事情)也是通过缩进的方式来表示的,跟之前分支和循环结构的代码块是一样的。
1.2函数的参数
如果函数中没有return
语句,那么函数默认返回代表空值的None
。另外,在定义函数时,函数也可以没有自变量,但是函数名后面的圆括号是必须有的。
-
位置参数——在没有特殊处理的情况下,函数的参数都是位置参数
-
关键字参数——我们在设计函数时,如果既不知道调用者会传入的参数个数,也不知道调用者会不会指定参数名,那么同时使用可变参数和关键字参数。关键字参数会将传入的带参数名的参数组装成一个字典,参数名就是字典中键值对的键,而参数值就是字典中键值对的值
重点提醒:关键字参数一定要在位置参数的后面。
代码例子如下:
# *args--->可变参数--->可以接收零个或任意多个位置参数--->将位置参数打包成元组 # **kwargs--->可以接收零个或任意多个关键字参数--->将所有的关键字参数打包成一个字典 def add(*args, **kwargs): print(args, type(args)) # print(kwargs, type(kwargs)) total = 0 for arg in args: if type(arg) in (int, float): total += arg for value in kwargs.values(): if type(value) in (int, float): total += value return total print(add(1, 2, 4, a=3)) def mul(*args, **kwargs): # print(args, type(args)) # print(kwargs, type(kwargs)) total = 1 for arg in args: if type(arg) in (int, float): total *= arg for value in kwargs.values(): if type(value) in (int, float): total *= value return total print(mul(1, 2, 4, a=3))
函数的例题一:
玩家摇两颗骰子,如果第一次摇出了7点或11点,玩家胜;如果摇出了2点、3点、12点,庄家胜; 如果摇出了其他的点数,游戏继续,玩家重新摇色子;如果玩家摇出了第一次摇的点数,玩家胜; 如果玩家摇出了7点,庄家胜;如果玩家摇出其他点数,游戏继续,玩家重新摇色子,直到分出胜负。 游戏开始之前,玩家有1000元的初始资金,玩家可以下注,赢了获得下注的金额,输了就扣除下注的金额, 游戏结束的条件是玩家把钱输光。
import random def roll_dice(num): """ 摇骰子 :param num: 骰子的数量 :return: 摇出的点数 """ total = 0 for _ in range(num): total += random.randrange(1, 7) return total def win(): global x print('玩家胜') x += z def lose(): global x print('庄家胜') x -= z x = 1000 while x > 0: print(f'玩家总资产为{x}元') z = 0 while z <= 0 or z > x: z = int(input('请下注')) m = roll_dice(3) print(f'玩家摇出了{m}点') if m in (7, 11): win() elif m in (2, 3, 12): lose() else: while True: n = roll_dice(3) print(f'玩家摇出了{n}点') if n == m: win() break elif n == 7: lose() break print('玩家已破产,游戏结束')
例题二:
# 求阶乘 def fac(num): """求阶乘""" result = 1 for i in range(2, num + 1): result *= i return result m = int(input('m = ')) n = int(input('n = ')) print(fac(m) // fac(n) // fac(m - n))
1.3标准库中的模块和函数
Python标准库中提供了大量的模块和函数来简化我们的开发工作,random
模块可以提供生成随机数和进行随机抽样的函数;而time
模块则可以提供和时间操作相关的函数。在Python标准库中的math
模块中还包括了计算正弦、余弦、指数、对数等一系列的数学函数。随着我们进一步的学习Python编程知识,我们还会用到更多的模块和函数。
Python标准库中还有一类函数是不需要import
就能够直接使用的,我们将其称之为内置函数,这些内置函数都是很有用也是最常用的,下面的表格列出了一部分的内置函数。
函数 | 说明 |
---|---|
abs | 返回一个数的绝对值,例如:abs(-1.3) 会返回1.3 。 |
bin | 把一个整数转换成以'0b' 开头的二进制字符串,例如:bin(123) 会返回'0b1111011' 。 |
chr | 将Unicode编码转换成对应的字符,例如:chr(8364) 会返回'€' 。 |
hex | 将一个整数转换成以'0x' 开头的十六进制字符串,例如:hex(123) 会返回'0x7b' 。 |
input | 从输入中读取一行,返回读到的字符串。 |
len | 获取字符串、列表等的长度。 |
max | 返回多个参数或一个可迭代对象(后面会讲)中的最大值,例如:max(12, 95, 37) 会返回95 。 |
min | 返回多个参数或一个可迭代对象(后面会讲)中的最小值,例如:min(12, 95, 37) 会返回12 。 |
oct | 把一个整数转换成以'0o' 开头的八进制字符串,例如:oct(123) 会返回'0o173' 。 |
open | 打开一个文件并返回文件对象(后面会讲)。 |
ord | 将字符转换成对应的Unicode编码,例如:ord('€') 会返回8364 。 |
pow | 求幂运算,例如:pow(2, 3) 会返回8 ;pow(2, 0.5) 会返回1.4142135623730951 。 |
print | 打印输出。 |
range | 构造一个范围序列,例如:range(100) 会产生0 到99 的整数序列。 |
round | 按照指定的精度对数值进行四舍五入,例如:round(1.23456, 4) 会返回1.2346 。 |
sum | 对一个序列中的项从左到右进行求和运算,例如:sum(range(1, 101)) 会返回5050 。 |
type | 返回对象的类型,例如:type(10) 会返回int ;而type('hello') 会返回str 。 |
二、高阶函数
Python中的函数是一等函数,但是函数本身也可以作为函数的参数或返回值,而且还可以赋值给变量。这就是所谓的高阶函数。通常使用高阶函数可以实现对原有函数的解藕合操作。
Lambda函数——没有名字而且一句话就能写完的函数,唯一的表达式就是函数的返回值。也被称为匿名函数
例如:
# fn ---> 一个实现二元运算的函数(可以做任意的二元运算) def calc(*args, op, init_value=0, **kwargs): total = init_value for arg in args: if type(arg) in (int, float): total = op(total, arg) for value in kwargs.values(): if type(value) in (int, float): total = op(total, value) return total # def add(x, y): # return x + y # # # def mul(x, y): # return x * y # print(calc(11, 22, 33, 44, op=add)) print(calc(11, 22, 33, 44, op=lambda x, y: x + y)) # print(calc(11, 22, 33, 44, op=mul, init_value=1)) print(calc(11, 22, 33, 44, init_value=1, op=lambda x, y: x * y)) fn = lambda x, y: x - y print(calc(11, 22, 33, 44, init_value=100, op=fn))
三、递归调用
函数如果直接或者间接的调用了自身,那么这种调用就被称为递归调用。
递归函数的两个要点:
- 递归公式(第n次跟第n-1次的关系)
- 收敛条件(什么时候停止递归调用)
# 不管函数是调用别的函数,还是调用自身,一定要做到快速收敛。 # 在比较有限的调用次数内能够结束,而不是无限制的调用函数。 # 如果一个函数(通常指递归调用的函数)不能够快速收敛,那么就很有可能产生下面的错误 # RecursionError: maximum recursion depth exceeded # 最终导致程序的崩溃。 def fac(num: int) -> int: """求阶乘(递归写法)""" if num == 0: return 1 return num * fac(num - 1) if __name__ == '__main__': # return 5 * fac(4) # return 4 * fac(3) # return 3 * fac(2) # return 2 * fac(1) # return 1 * fac(0) # return 1 print(fac(5)) def fib(n): if n in (1, 2): return 1 return fib(n - 1) + fib(n - 2) if __name__ == '__main__': for i in range(1, 21): print(i, fib(i))
例题一:编写实现对列表元素进行冒泡排序的函数
def bubble_sort(items, ascending=True, gt=lambda x, y: x > y): """ 冒泡排序 :param items: 待排序的列表 :param ascending: :param gt: :return: """ items = items[:] for i in range(1, len(items)): swapped = False for j in range(0, len(items) - i): if gt(items[j], items[j + 1]): items[j], items[j + 1] = items[j + 1], items[j] swapped = True if not swapped: break if not ascending: items = items[::-1] return items if __name__ == '__main__': nums = [35, 96, 12, 7, 20, 8, 15] print(bubble_sort(nums, ascending=False)) print(nums)
例题二:编写实现查找列表元素的函数:
def seq_search(items: list, key) -> int: """ 顺序查找 :param items: 待查找的元素 :param key: 要找的元素 :return: 找到了返回元素的索引,找不到返回-1 """ for index, item in enumerate(items): if item == key: return index return -1 def bin_search(items: list, key) -> int: """ 二分查找 :param items:待查找的元素(元素有序) :param key: 要找的元素 :return: 找到了返回元素的索引,找不到返回-1 """ start, end = 0, len(items) - 1 while start <= end: mid = (start + end) // 2 if key > items[mid]: start = mid + 1 elif key < items[mid]: end = mid - 1 else: return mid return -1 if __name__ == '__main__': nums1 = [5, 4, 7, 20, 8, 15] print(seq_search(nums1, 20)) print('_' * 20) nums2 = [4, 5, 7, 8, 15, 20] print(bin_search(nums2, 15)) print(bin_search(nums2, 45))
四、面向对象编程
1、定义
面向对象编程是一种编程范式(程序设计的方法论)。
如果要用一句话来概括面向对象编程,我认为下面的说法是相当精准的。
面向对象编程:把一组数据和处理数据的方法组成对象,把行为相同的对象归纳为类,通过封装隐藏对象的内部细节,通过继承实现类的特化和泛化,通过多态实现基于对象类型的动态分派。
对象:对象是可以接收消息的实体,面向对象编程就行通过给对象发消息达到解决问题的目标。对象 = 数据 + 函数(方法),即对象将数据和操作数据的函数从逻辑上变成了一个整体。
对象有以下四个特征:
- 一切皆为对象
- 对象都有属性和行为
- 每个对象都是独一无二的
- 对象一定属于某个类
类:将有共同特征(静态特征和动态特征)的对象的共同特征抽取出来之后得到的一个抽象概念。简单的说,类是对象的蓝图(模板),有了类才能够创建出这种类型的对象。
2、创建和使用对象
1、定义类:类的命名使用驼峰命名法(每个单词首字母大写)
数据抽象:找到和对象相关的静态特征(属性)
行为抽象:找到和对象相关的动态特征(方法)
2、创建对象
3、给对象发消息
例如:
# 第一步:定义类 class Student: """学生""" # 数据抽象(属性) def __init__(self, name, age): self.name = name self.age = age # 行为抽象(方法) def eat(self, name): """吃饭""" print(f'{self.name}正在吃{name}') def study(self, course_name): """ 学习 :param course_name: 课程名字 """ print(f'{self.name}正在学习{course_name}') def play(self, game_name): """ 玩耍 :param game_name: 游戏名字 """ print(f'{self.name}正在玩{game_name}') # 第二步:创建对象--->构造器语法--->类名(..., ...) Stu1 = Student('黄小宇', 18) Stu2 = Student('周大大', 21) # Student.study(stu1, 'Python程序设计') # 第三步:给对象发消息(调用对象的方法) Stu1.eat('螺蛳粉') Stu2.study('Python程序设计')
3、魔术方法
-
魔术方法(魔法方法)—> 有特殊用途和意义的方法
- init —> 初始化方法,在调用构造器语法创建对象的时候会被自动调用
- str —> 获得对象的字符串表示,在调用print函数输出对象时会被自动调用
-
repr —> 获得对象的字符串表示,把对象放到容器中调用print输出时会自动调用
—> representation - lt —> 在使用 < 运算符比较两个对象大小时会自动调用
如果一个变量的取值只有有限个选项,可以考虑使用枚举类型。
Python中没有定义枚举类型的语法,但是可以通过继承Enum类来实现枚举类型。
结论1:枚举类型是定义符号常量的最佳选择!!!
结论2:符号常量(有意义的名字)总是优于字面常量!!
4、继承和多态
继承:对已有的类进行扩展创建出新的类,这个过程就叫继承。
提供继承信息的类叫做父类(超类、基类),得到继承信息的类称为子类(派生类)。
继承是实现代码复用的一种手段,但是千万不要滥用继承。
继承是一种is-a关系。
a student is a person.
a teacher is a person.
a programmer is a person.
子类直接从父类继承公共的属性和行为,再添加自己特有的属性和行为,
所以子类一定是比父类更强大的,任何时候都可以用子类对象去替代父类对象。
Python中的继承允许多重继承,一个类可以有一个或多个父类。
如果不是必须使用多重继承的场景下,请尽量使用单一继承。
5、两个类之间有哪些关系
~ is-a关系:继承—>从一个类派生出另一个类
a student is a person
~ has-a关系:关联—>把一个类的对象作为另外一个类的对象的属性
a person has an identity card
——(普通)关联
-
—— 强关联:整体和部分的关联,聚合和合成
-
use-a关系:依赖—>一个类的对象作为另外一个类的方法的参数或返回值
a person use a vehicle(交通工具)
6、面向对象编程的四大支柱
1、抽象(abstraction):提取共性(定义类就是一个抽象过程,需要做数据抽象和行为抽象)
2、封装(encapsulation):把数据和操作数据的函数从逻辑上组成一个整体(对象)
—>隐藏实现细节,暴露简单的调用接口
3、继承(inheritance):扩展已有的类创建新类,实现对已有类的代码复用
4、多态(polymorphism):给不同的对象发出同样的消息,不同的对象执行了不同的行为。
—>方法重写(override):子类对父类已有的方法,重新给出自己的实现版本
在重写方法的过程中,不同的子类可以对父类的同一个方法给出不同的实现版本,
那么该方法在运行时就会表现出多态性
7 经典例题
例题一:
-
现在有三类员工:
- 部门经理:固定月薪,15000
- 程序员:计时结算月薪,
-
销售员:底薪 + 提成,底薪1800,销售额 %5提成
写一个面向对象的编程实现工资的计算
from abc import abstractmethod class Employee: def __init__(self, name): self.name = name @abstractmethod def get_salary(self): pass class Manager(Employee): def get_salary(self): return 15000 class Programmer(Employee): def __init__(self, name): super().__init__(name) self.working_hour = 0 def get_salary(self): return 200 * self.working_hour class Salesman(Employee): def __init__(self, name): super().__init__(name) self.sales = 0 def get_salary(self): return 1800 + 0.05 * self.sales def main(): emps = [Manager('刘备'), Programmer('诸葛亮'), Salesman('关羽')] for emp in emps: if type(emp) == Programmer: emp.working_hour = int(input(f'请输入{emp.name}本月工作时长')) elif type(emp) == Salesman: emp.sales = int(input(f'请输入{emp.name}本月销售额')) print(f'{emp.name}本月工资:{emp.get_salary()}元') if __name__ == '__main__': main()
例题二:
# 创建一个时钟对象(可以显示时/分/秒),让它运转起来 import time class Clock: # 数据抽象 def __init__(self, hour=0, minute=0, second=0): self.hour = hour self.min = minute self.sec = second def show(self): """显示时间""" return f'{self.hour:0>2d}:{self.min:0>2d}:{self.sec:0>2d}' # 行为抽象 def run(self): """走字""" self.sec += 1 if self.sec == 60: self.sec = 0 self.min += 1 if self.min == 60: self.min = 0 self.hour += 1 if self.hour == 24: self.hour = 0 if __name__ == '__main__': clock = Clock() while True: print(clock.show()) time.sleep(1) clock.run()
五、总结
Python中的函数可以使用可变参数*args
和关键字参数**kwargs
来接收任意数量的参数,而且传入参数时可以带上参数名也可以没有参数名,可变参数会被处理成一个元组,而关键字参数会被处理成一个字典。Python中的函数也是对象,所以函数可以作为函数的参数和返回值,也就是说,在Python中我们可以使用高阶函数。如果我们要定义的函数非常简单,只有一行代码且不需要名字,可以将函数写成Lambda函数(匿名函数)的形式。
面向对象编程是一种非常流行的编程范式,除此之外还有指令式编程、函数式编程等编程范式。由于现实世界是由对象构成的,而对象是可以接收消息的实体,所以面向对象编程更符合人类正常的思维习惯。类是抽象的,对象是具体的,有了类就能创建对象,有了对象就可以接收消息,这就是面向对象编程的基础。定义类的过程是一个抽象的过程,找到对象公共的属性属于数据抽象,找到对象公共的方法属于行为抽象。
这周的函数和面向对象编程是重点,也是难点。需要反复的去巩固练习,需要用时间去练习,以此来让我们能够熟练的掌握。
这篇关于学习Python第三周总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器