从零开始的python学习(七)P89+P90+P91+P92+P93+P94
本文章记录观看B站python教程学习笔记和实践感悟,视频链接:【花了2万多买的Python教程全套,现在分享给大家,入门到精通(Python全栈开发教程)】 https://www.bilibili.com/video/BV1wD4y1o7AS/?p=6&share_source=copy_web&vd_source=404581381724503685cb98601d6706fb
上节课学习本章总结和章节选择题,实战一:输入成绩如果不正确手动抛出异常,实战二:判断是否构成三角形,本节课学习函数的定义及调用,函数的参数传递-位置传参和关键字传参,函数的参数传递-默认值参数,函数的参数传递-可变参数,函数的返回值,变量的作用域。
1.函数的定义及调用
内置函数就是python中已经写好的函数,本章节就是学习如何自定义函数。其中函数名称是自己起的,参数可以有很多个,执行函数功能的部分就是函数体,这里如果没有返回值,return可以不写。
#定义函数
def 自己起一个名字(参数列表可以不止一个):函数体
return
#函数的调用
自己起的那个名字(设置参数)
下面是具体的例子:
#下面演示一下一个自定义函数的例子比方说下面为一个计算累加和的例子
def get_sum(num): #因为只有输入才知道这个位置是具体的谁,因此num又叫做形式参数s=0for i in range(1,num+1):#这里是num+1是因为我们最后需要加上num,小括号的右端是不包括的s+=iprint(f'1到{num}之间的累加和为:{s}') #至此函数体部分就写完了
#函数的调用这里我们以下述设置参数为例,具体的数值叫做实际参数
get_sum(10)#累加1到10
get_sum(100)#累加1到100
get_sum(1000)#累加1到1000
运行结果如下:
注意看这里的“3”表示调用了三次,点开能看到在哪一行被调用的。
总结:
2.函数的参数传递-位置传参和关键字传参
第一个例子:位置参数,就是传入的时候必须跟设置的参数的位置一一对应
#下面是未位置参数的例子,根据定义时参数设置的位置(个数和先后位置)往里面传参
def happy_birthday(name,age):print('祝'+name+'生日快乐')print(str(age)+'生日快乐')#调用,参数设置上必须个数和顺序都相同
#happy_birthday('娟子姐') #报错显示少参数:TypeError: happy_birthday() missing 1 required positional argument: 'age'
#happy_birthday(18,'娟子姐')#报错显示数据类型连接错误:TypeError: can only concatenate str (not "int") to str
happy_birthday('娟子姐',18)
实验结果:
第二个例子关键字传参,这个不需要严格遵守位置。要求名称必须与函数定义的参数的名称一致。否则就会报错unexpected keyword
#下面是关键字参数的例子,直接把参数对应赋值了
def happy_birthday(name,age):print('祝'+name+'生日快乐')print(str(age)+'生日快乐')
#关键字符串
#happy_birthday(age=18,name1='娟子姐') #报错没有name1这个参数:TypeError: happy_birthday() got an unexpected keyword argument 'name1'
happy_birthday(age=18,name='娟子姐')
结果:
第三个例子,在一个函数的参数传递中,既可以使用位置传参,也可以使用关键字传参。但是如果既有位置传参又有关键字传参必须位置传参在前,关键字传参在后。
#下面是两种传参数混合的例子,必须位置传参在前。关键字传参在后
def happy_birthday(name,age):print('祝'+name+'生日快乐')print(str(age)+'生日快乐')
#
#happy_birthday(age=18,name1='娟子姐') #报错没有name1这个参数:TypeError: happy_birthday() got an unexpected keyword argument 'name1'
#happy_birthday(name='娟子姐',18) #报错语法错误,位置传参必须在前:SyntaxError: positional argument follows keyword argument
#happy_birthday(18,name='娟子姐') #报错第一个参数的赋值产生了混乱:TypeError: happy_birthday() got multiple values for argument 'name'
happy_birthday('娟子姐',age=18) #正常执行
3.函数的参数传递-默认值参数
当位置参数和关键字参数同时存在时,应该遵循位置参数在前,默认值参数(只有在函数调用时传参的时候才叫关键字参数)在后。定义时赋值叫做默认值参数。
举例:
def happy_birthday(name='娟子姐',age=18):print('祝'+name+'生日快乐')print(str(age)+'生日快乐')
#传参因为在定义的时候定义了默认值,所以在调用的时候就可以不传参
happy_birthday() #如果不传参
happy_birthday('小美') #位置传参,传了一个参数。剩下没被定义的就把默认值传进去
happy_birthday(age=19) #关键字传参,传了一个参数,剩下没被定义的就把默认值传进去
#happy_birthday(19) #19被传给了name因此报错:TypeError: can only concatenate str (not "int") to str#当位置参数和关键字参数同时存在时,应该遵循位置参数在前,默认值参数(只有在函数调用时传参的时候才叫关键字参数)在后
def fun(a,b=20): #a作为位置参数,b为默认值参数pass
#def fun2(a=20,b): #报错,语法错误,因为当位置参数和默认值参数同时存在时,b作为位置参数在后了
# pass
4.函数的参数传递-可变参数
一颗星和两颗星两种例子:注意这里面我们用的参数名para和kwpara都是可以自定义的
1.个数可变的位置参数
这里涉及到*加上参数可以实现不限量的位置传参,而且在输入元组的时候加上*可以对其解包。
#注意这里面我们用的参数名para和kwpara都是可以自定义的
#一:个数可变的位置参数
def fun(*para):print(type(para))for i in para:print(i)#调用(这里传几个都可以。因为参数的数目不固定)
fun(10,20,30,40) #这里传了四个值
fun(40) #这里传了一个值
fun([11,22,33,44]) #这里传了一个列表,但是把整个列表定义为了一个元素,结果是[11, 22, 33, 44]
#在调用时。参数前加一颗星,此时会将列表进行解包
fun(*[11,22,33,44])
结果如下:
2.个数可变的关键字参数
注意字典是不可以直接传进去作为位置参数的,因为定义的是可变的关键字传参因此必须是“xx=...”这种赋值的形式
例子:
#二:个数可变的关键字参数,这里kwpara是一个字典
def fun2(**kwpara):print(type(kwpara))for key,value in kwpara.items():print(key,'------',value)#调用
fun2(name='娟子姐',age=18,height=170) #关键字参数
#注意字典是不可以直接传进去作为位置参数的,因为定义的是可变的关键字传参因此必须是“xx=...”这种赋值的形式
d={'name':'娟子姐','age':18,'height':170}
#fun2(d) #报错AttributeError: 'dict' object has no attribute 'item'
fun2(**d) #这样可以使用系列解包的形式
结果:
5.函数的返回值
带有返回值的函数,在函数调用时可以存储到变量中,也可以直接参与下一次进行计算。
返回值只有一个的:
#函数的返回值
def calc(a,b):print(a+b)
calc(10,20)
print(calc(1,2)) #输出结果为None,这说明了定义的这个函数没有使用return去返回任何结果def calc2(a,b):s=a+breturn s #将s返回给函数的调用处去处理
print('-'*10)
get_s=calc2(1,2) #当计算完a+b后要把它存储到一个变量get_s当中
print(get_s)#第二种情况
get_s2=calc2(calc2(1,2),3) #先去执行calc2(1,2)返回结果为3,再去执行calc2(3,3)
print(get_s2)
当返回值有多个时:
#返回值可以是多个
def get_sum(num):sum=0 #累加和odd_sum=0 #奇数和even_sum=0 #偶数和for i in range(1,num+1):if i % 2 != 0: #说明是奇数odd_sum+=ielse:even_sum+=isum+=ireturn odd_sum,even_sum,sum #返回三个值
result=get_sum(10)
print(type(result))
print(result)#解包赋值
a,b,c=get_sum(10)#返回三个值,元组类型
print(a)
print(b)
print(c)
结果如下:
6.变量的作用域
下面进行实验:
#变量的作用域
def calc(a,b):s=a+breturn sprint(a,b,s) #其中a,b是函数的参数,属于局部变量;s是函数中定义的变量,也是局部变量
报错:这说明了print那一行其实超出了abs的作用范围
Traceback (most recent call last):File "D:\pycharm_project\learn_pytorch\pythonProject1\2practice\p94.py", line 6, in <module>print(a,b,s) #其中a,b是函数的参数,属于局部变量;s是函数中定义的变量,也是局部变量
NameError: name 'a' is not defined进程已结束,退出代码为 1
下面程序调试,代码修正如下处理:
#变量的作用域
def calc(a,b):s=a+breturn s
result=calc(10,20)
print(result)
#print(a,b,s) #其中a,b是函数的参数,属于局部变量;s是函数中定义的变量,也是局部变量
在第五行设置断点:
点击小虫:,然后点击逐步执行:
如下图所示,执行到第四行的时候分别给a,b,s赋上了值。
点击步过,此时所有的变量都没有,那是因为这三个的作用域都结束了:
再点一下步过继续向下执行:
是函数的输出结果即result为30
再考虑全局变量,就是对于该行以下的所有python文件内容都有效
当全局变量和局部变量名称相同时。局部变量的优先级更高
a=100 #全局变量作用域是整个python文件中
def calc(x,y):return a+x+y
print(a)
print(calc(10,20))
print('-'*30)
#考虑当全局变量与局部变量重名了,会以什么为准
#回答:当全局变量和局部变量名称相同时。局部变量的优先级更高
def calc2(x,y):a=200 #局部变量,局部变量的名称和全局变量名称相同return a+x+y #此时a是全局变量还是局部变量?局部变量print(calc2(10,20)) #230,说明上面那个a+x+y的a是局部变量
print(a) #此时这就是全局变量a了
print('-'*30)
def calc3(x,y):global s #s是在函数中定义的变量,但是使用了global关键字声明,这个变量变成了全局变量s=300 #声明和赋值return s+x+yprint(calc3(10,20)) #输出330,10+20+300
print(s)
结果如下:
本节完