Python学习笔记:第十站 水晶球不调用不动
Python学习笔记
文章目录
- Python学习笔记
- 第十站 水晶球不调用不动
- 1. 函数的创建和调用
- 2. 函数的参数传递
- 3. 函数的返回值
- 4. 函数的参数定义
- 5. 变量的作用域
- 6. 递归函数
- 7. 本章作业
课程笔记参考B站视频: Python全栈开发教程。
第十站 水晶球不调用不动
这个水晶球就是“函数”。
1. 函数的创建和调用
函数就是执行特定任和以完成特定功能的一段代码。函数的优点包括:复用代码、隐藏实现细节、提高可维护性、提高可读性便于调试等。函数的创建和调用格式如下:
'''函数的创建格式'''
def 函数名([形式参数]):函数体[return xxx]'''函数的调用格式'''
函数名([实际参数])
注:要先定义函数,才能进行调用。
下面是代码示例:
def cal(a,b):c=a+breturn cresult = cal(10, 20)
print(result)
- 运行结果
30
2. 函数的参数传递
函数调用的参数传递主要有两种方式:
- 按照位置传递实参:根据 形参对应的位置 进行实参传递,顺序不可改变。
- 按照关键字传递实参:根据 形参名称 进行实参传递,顺序可以改变。
下面是代码示例:
def cal(a,b):c=a+breturn cprint('位置传递:', cal(10, 20))
print('关键字传递:', cal(b=20,a=100)) # 左侧的变量名称称为关键字参数
- 运行结果
30
120
下面以一个程序来举例,说明函数调用时参数传递的内存分析图。
def fun(arg1, arg2):print('arg1=', id(arg1), arg1)print('arg2=', id(arg2), arg2)arg1 = 100arg2.append(10)print('arg1=', id(arg1), arg1)print('arg2=', id(arg2), arg2)# returnn1 = 11
n2 = [22, 33, 44]
print('调用函数前:', id(n1), n1)
print('调用函数前:', id(n2), n2)
print('---调用函数中----')
fun(n1, n2)
print('----------------')
print('调用函数后:', id(n1), n1)
print('调用函数后:', id(n2), n2)
上面这个程序在运行的过程中,其内存分析图如下:
最终其运行结果为:
调用函数前: 140718152341472 11
调用函数前: 2535859027008 [22, 33, 44]
---调用函数中----
arg1= 140718152341472 11
arg2= 2535859027008 [22, 33, 44]
arg1= 140718152344320 100
arg2= 2535859027008 [22, 33, 44, 10]
----------------
调用函数后: 140718152341472 11
调用函数后: 2535859027008 [22, 33, 44, 10]
即,在函数调用过程中,进行参数的传递:
- 如果是不可变对象,在函数体的修改不会影响实参的值。
- 如果是可变对象,在函数体的修改会影响实参的值。
3. 函数的返回值
函数的返回值有如下情况:
- 若函数没有返回值,
return
可以省略不写。- 若函数的返回值只有1个,直接返回其类型。
- 若函数的返回值有多个,返回的结果为元组。
下面是代码示例:
def fun(num):odd = [] # 定义空列表even = []for i in num:if i%2:odd.append(i)else:even.append(i)return odd, evenresult = fun(range(-1,-10,-1))
print(result)
print('奇数列表为:', result[0])
print('偶数列表为:', result[1])
- 运行结果
([-1, -3, -5, -7, -9], [-2, -4, -6, -8])
奇数列表为: [-1, -3, -5, -7, -9]
偶数列表为: [-2, -4, -6, -8]
4. 函数的参数定义
函数的参数定义除了可以直接声明变量,还有三种特殊方式:
- 默认值参数:函数定义时给形参设置默认值,只有与默认值不符的时候才需要传递实参。
- 个数可变的位置参数:适用于无法确定要传递的位置实参的个数时,使用
*
定义,类型为元组- 个数可变的关键字参数:适用于无法确定要传递的关键字实参的个数时,使用
**
进行定义,类型为字典。注:对于第二种和第三种参数,只能定义一个。
注:若同时都有定义,第二种必须放在第三种之前(两个星号的必须在前面)。
下面是代码示例:
def fun1(a, b=10): # 默认值参数print(a, b)returndef fun2(*args): # 可变的位置参数print(args)def fun3(**args): # 可变的位置参数print(args)def fun4(*args1, **args2): # 不会报错pass
# def fun5(**args1, *args2): # 会报错,SyntaxError: invalid syntax
# passprint('---------默认值参数---------')
print('传递1个参数:', fun1(100))
print('传递2个参数:', fun1(100, 20))
print('-----个数可变的位置参数------')
fun2(10)
fun2(10, 20)
fun2(10, 20, 30)
print('-----个数可变的关键字参数-----')
fun3(a=10)
fun3(a=10, b=20)
fun3(a=10, b=20, c=30)
- 运行结果
---------默认值参数---------
100 10
传递1个参数: None
100 20
传递2个参数: None
-----个数可变的位置参数------
(10,)
(10, 20)
(10, 20, 30)
-----个数可变的关键字参数-----
{'a': 10}
{'a': 10, 'b': 20}
{'a': 10, 'b': 20, 'c': 30}
同时从上面的代码结果中可以看出,一条语句包含函数时,会首先运行函数体,再运行该条语句。
最后总结一下函数的参数类型:
分类 | 参数的类型 | 备注 |
---|---|---|
函数的调用 | 位置实参 | |
将元组、列表、集合的每个元素都转换成位置实参 | 使用* | |
关键字实参 | ||
将字典的所有键值对都转换成关键字实参 | 使用** | |
函数的定义 | 默认值形参 | |
关键字形参 | 使用* | |
个数可变的位置形参 | 使用* | |
个数可变的关键字形参 | 使用** |
下面是函数的调用代码示例:
def fun(a, b, c):print('a =', a, ' b =', b, ' c =', c)print('-----函数调用实参的不同方式------')
print('位置实参:', end='')
fun(10, 20, 30) # 位置实参
print('元组、列表、集合转换成位置实参:', end='')
lst = {40, 50, 60} # 元组、列表、集合都可以
fun(*lst) # 调用时将每个元素都转换成 位置实参
print('关键字实参:', end='')
fun(a=70, b=80, c=90) # 关键字实参
print('字典转换成关键字实参:', end='')
dic = {'a':100, 'b':110, 'c':130}
fun(**dic) # 调用时将所有键值对都转换成 关键字实参
- 运行结果
-----函数调用实参的不同方式------
位置实参:a = 10 b = 20 c = 30
元组、列表、集合转换成位置实参:a = 40 b = 50 c = 60
关键字实参:a = 70 b = 80 c = 90
字典转换成关键字实参:a = 100 b = 110 c = 130
下面是函数的定义代码示例:
def fun1(a, b=10): # a为位置形参,b为默认值形参print('a =', a, ' b =', b)def fun2(*args): # 个数可变的位置形参print(args)def fun3(**args): # 个数可变的关键字形参print(args)def fun4(a,b,c):print('a =', a, ' b =', b, ' c =', c)def fun5(a,*,b,c): # 星号后面都必须使用关键字实参print('a =', a, ' b =', b, ' c =', c)print('-------演示fun1()---------')
print('-------演示fun2()---------')
fun2(10, 20, 30)
print('-------演示fun3()---------')
fun3(a=10, b=20)
print('-------演示fun4()---------')
fun4(10, 20, 30) # 位置实参
fun4(a=40, b=50, c=60) # 关键字实参
fun4(40, 50, c=60) # 前两个位置实参,后一个关键字实参
print('-------演示fun5()---------')
# fun5(40, 50, c=60) # 会报错说少一个关键字实参
fun5(40, c=50, b=60)
- 运行结果
-------演示fun1()---------
-------演示fun2()---------
(10, 20, 30)
-------演示fun3()---------
{'a': 10, 'b': 20}
-------演示fun4()---------
a = 10 b = 20 c = 30
a = 40 b = 50 c = 60
a = 40 b = 50 c = 60
-------演示fun5()---------
a = 40 b = 60 c = 50
函数定义参数时的顺序(从前到后):位置形参 > 关键字形参、可变数量位置形参 > 可变数量关键字形参。若有一个单独的星号(表明其后面都是关键字形参),则可变数量位置形参一定要提前到该星号之前。
5. 变量的作用域
变量的作用域指的是程序代码能访问该变量的区域,在作用域之外调用变量会报错。根据变量的有效范围可分为:
- 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量
就会就成全局变量。- 全局变量:函数体外定义的变量,可作用于函数内外。
在下面这段代码中,c
称为局部变量,变量a, b
作为函数的形参,作用范围也是函数内部,也就是局部变量。于是在函数体外部调用a, b, c
就会报错。
def fun(a, b):c = a+b # c称为局部变量print(c)# print(a) # 会报错
在下面这段代码中,name
是全局变量,在函数体内部和外部都可以使用,所以会打印两次。(C/C++不是这样的!!)
def fun2():print(name)name = '张三'
print(name)
fun2()
- 运行结果
张三
张三
下面这段代码中,age
本来作为局部变量,只能作用于函数体内部,但其使用 global
声明,就成为全局变量,在函数体外部也可以调用。
def fun3():global notenote = '去码头整点薯条'print(note)fun3()
print(note)
- 运行结果
去码头整点薯条
去码头整点薯条
6. 递归函数
如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数。递归(递推、回归)由 递归调用 与 递归终止条件 两部分组成。进行递归时,每递归调用一次函数,都会在栈内存分配一个栈帧,当执行完本次函数,就会释放相应的空间只返回结果,如此循环直到完成整个递归。递归的优缺点如下:
缺点:占用内存多,效率低下。
优点:思路和代码简单。
下面是代码示例:
'''递归计算阶乘'''
def fac(n):if(n==1):return 1else:res = n*fac(n-1)return resprint('4的阶乘为:', fac(4))
- 运行结果
4的阶乘为: 24
在调用递归函数的语句打上断点,进入调试模式,然后一直执行步入(step into),便可以在调试(debugger)窗口看到函数fac递推到回归的整个过程。
课堂作业:使用递归完成斐波那契数列的计算。
下面是代码示例:
'''
斐波那契数列:前两项均为1,此后的每一位都是前两项的和。
'''
'''下面这个函数体没有用到递归但是算出来了'''
'''函数体功能:输入序列长度,返回相应长度的斐波那契数列。'''
def fibo_sequ(mindex):sequ=[1]index = 1while index<mindex:if (index == 1):sequ.append(1)else:sequ.append(sequ[-1]+sequ[-2])index += 1return sequ
print(fibo_sequ(6))'''使用递归,但是只能计算单个元素的值'''
'''函数体功能:使用递归计算单个索引下的斐波那契数列值'''
def fib(n):if(n==1):return 1elif(n==2):return 1else:return fib(n-1)+fib(n-2)
for i in range(1,7,1):print(fib(i), end=' ')
- 运行结果
[1, 1, 2, 3, 5, 8]
1 1 2 3 5 8
设置输出100个斐波那契数列的值,可以观察到使用递归的方法会非常的慢。并且从代码逻辑上说,显然使用递归会非常的浪费内存。
7. 本章作业
1. Mini计算器
说明:使用函数完成加、减、乘、除运算。
下面是代码示例:
def mini_cal(a, b, operation):if operation=='+':return a+belif operation=='-':return a-belif operation=='*':return a*belif operation=='/':if b!=0:return a/belse:return '除数不能为0'else:return '运算符输入错误'
if __name__ == '__main__':a = int(input('请输入第一个整数:'))b = int(input('请输入第一个整数:'))oper = input('请输入运算符:')print(mini_cal(a, b, oper))
- 运行结果
请输入第一个整数:10
请输入第一个整数:0
请输入运算符:/
除数不能为0
2. 猜数游戏
说明:使用函数完成猜数游戏。
下面是代码示例:
import random
def guess(num_rand, num_guess):if num_rand>num_guess:return '猜小了'elif num_rand<num_guess:return '猜大了'elif num_rand==num_guess:return '猜对了'
if __name__=='__main__':num_rand = random.randint(0,100)for i in range(7,0,-1):num_guess = int(input('请输入一个0~100的整数:'))res = guess(num_rand,num_guess)if res!='猜对了' and i>1:print(res + f',你还有 {i-1} 次机会')elif res!='猜对了' and i==1:print(res + ',机会已经用完了~')else:print(res)break
- 运行结果
请输入一个0~100的整数:50
猜大了,你还有 6 次机会
请输入一个0~100的整数:25
猜小了,你还有 5 次机会
请输入一个0~100的整数:37
猜大了,你还有 4 次机会
请输入一个0~100的整数:31
猜小了,你还有 3 次机会
请输入一个0~100的整数:34
猜对了
Python学习笔记:第十站 水晶球不调用不动相关推荐
- Python学习笔记第二十九天(N维数组(ndarray))
Python学习笔记第二十九天 N维数组(ndarray) 构建阵列 索引阵列 ndarray的内部内存布局 阵列属性 内存布局 数据类型 其他属性 阵列接口 ctypes外部功能接口 Array方法 ...
- Python学习笔记(十九)面向对象 - 继承
Python学习笔记(十九)面向对象 - 继承 一.继承的概念 # 继承:子类继承父类的所有方法和属性# 1. 子类 class A(object):def __init__(self):self.n ...
- Python学习笔记:第二站 七十二变
Python学习笔记 文章目录 Python学习笔记 第二站 七十二变 1. 二进制与字符编码 2. Python中的标识符与保留字 3. Python中的变量 4.Python中的数据类型 5. P ...
- Python学习笔记:第九站 一串连一串
Python学习笔记 文章目录 Python学习笔记 第九站 一串连一串 1. 字符串的驻留机制 2. 字符串的常用操作 3. 字符串的比较 4. 字符串的切片操作 5. 格式化字符串 6. 字符串的 ...
- 【Python学习笔记】b站@同济子豪兄 用pytorch搭建全连接神经网络,对Fashion-MNIST数据集中的时尚物品进行分类
[Python学习笔记]原作b站@同济子豪兄 用pytorch搭建全连接神经网络,对Fashion-MNIST数据集中的时尚物品进行分类 跟着b站@同济子豪兄的视频自学写的代码,内容是用pytorch ...
- Python学习笔记(十五):类基础
以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-24 23:59 学习笔记 1,Python中的大多 ...
- Python学习笔记(十九)——Matplotlib入门
目录 Matplotlib简介 导入matplotlib模块 图的参数说明 matplotlib图像组成部分介绍 matplotlib绘图步骤分析 matplotlib实现简单图像 matplotli ...
- Python学习笔记整理(十五)类的编写细节
类代码编写细节 一.class语句 一般形式 class <name>(superclass,...): data=value def mothod(self,... ...
- python学习笔记(十二)标准库os
os 模块提供了访问操作系统服务的功能,它所包含的内容比较多. >>> import os >>> dir(os) ['EX_CANTCREAT', 'EX_CON ...
最新文章
- HttpSender OkHttp+RxJava超好用、功能超级强大的Http请求框架
- Windows Azure Platform Introduction (2) 云计算的分类和服务层次
- SDCC 2015架构专场札记:一线互联网公司的架构实践
- 对于redis底层框架的理解(一)
- python 获取向上两级路径_全国计算机二级Python真题解析-1
- bzoj 4319 cerc2008 Suffix reconstruction——贪心构造
- mysql数据库插入datetime_往MySQL数据库datetime类型字段中插入数据库的当前时间
- ASP.NET中 DataGrid简单自定义分页
- Oracle学习笔记:手工注册oracle的oledb驱动
- It seems that scikit-learn has not been built correctly.
- 中的draw函数_哪一个热图函数更快?
- 设计模式17---设计模式之模板方法模式(Template Method)(行为型)
- 几种经典病毒动力学模型【基于matlab的动力学模型学习笔记_3】
- 金蝶登录服务器不显示名称,金蝶云服务器如何登陆不了
- 微信支付 postman_小刘同学微信支付接入全笔记
- 解决安装ENVI5.3报错:the installation of MSVC_2010_SP1_x64_32bit has failed
- 别再眼红别人家的年终奖了,这才是大多数人的现状!
- 场景化AI数据推动智慧家居发展
- Excel 操作 插件 方方格子 工作簿未按字母顺序排列 重名工作簿名 并拆分成工作表
- SpringCloud和SpringCloudAlibaba的区别