Python基础03 :函数、递归、内置函数
1.函数基本语法及特性
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
特性:
- 减少重复代码
- 使程序变的可扩展
- 使程序变得易维护
语法定义
1 def sayhi():#函数名 2 print("Hello, I'm nobody!") 3 4 sayhi() #调用函数
可以带参数
1 #下面这段代码 2 a,b = 5,8 3 c = a**b 4 print(c) 5 6 7 #改成用函数写 8 def calc(x,y): 9 res = x**y 10 return res #返回函数执行结果 11 12 c = calc(a,b) #结果赋值给c变量 13 print(c)
2.函数参数与局部变量
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

位置参数
普通的参数叫位置参数,通常在调用一个函数的时候,粗心的程序员很容易搞乱位置参数的顺序,以至于函数无法按照预期实现。因此,有了关键字参数
关键字参数
def saySomething(name, words): print(name + '-->' + words) saySomething("小甲鱼", "让编程改变世界") # 小甲鱼-->让编程改变世界 saySomething("让编程改变世界", "小甲鱼") # 让编程改变世界-->小甲鱼 容易将位置搞混 saySomething(words = "让编程改变世界", name = "小甲鱼") # 小甲鱼-->让编程改变世界 # 注意:关键字参数必须放在默认参数之后,否则会报错 saySomething(words = "让编程改变世界", "小甲鱼") ''' File "E:/PycharmProjects/s14/day3/func_01.py", line 14 saySomething(words = "让编程改变世界", "小甲鱼") ^ SyntaxError: positional argument follows keyword argument '''
默认参数
初学者很容易搞混关键字参数和默认参数,默认参数是在定义的时候赋予了默认值的参数:
def saySomething(name="小甲鱼", words="让编程改变世界"): print(name + '-->' + words) saySomething() #小甲鱼-->让编程改变世界 saySomething("苏轼", "不识庐山真面目,只缘身在此山中") #苏轼-->不识庐山真面目,只缘身在此山中 # 注意:默认参数需要在位置参数后,否则报错 def saySomething(name="小甲鱼", words): print(name + '-->' + words) ''' File "E:/PycharmProjects/s14/day3/func_01.py", line 3 def saySomething(name="小甲鱼", words): ^ SyntaxError: non-default argument follows default argument '''
使用默认参数的话,可以不带参数去调用函数。
关键字参数:函数调用时,通过参数吗指定要赋值的参数,这样做就不怕因为搞不清参数的顺序而导致函数调用出错。
默认参数:参数定义的过程中,为形参赋初值,当函数调用的时候,不传递实参,则默认使用形参的初始值代替。
收集参数
若你的函数在定义时不确定用户想传入多少个参数,就可以使用收集参数
1 # 收集参数 2 def test(*args): # *args 会把多传入的参数变成一个元组形式 3 print("有 %d 个参数:" % len(args)) 4 print("参数的类型:%s" % type(args)) 5 print("第二个参数是:", args[1]) 6 test('F', 'i', 's', 'h', 'C') 7 ''' 8 有 5 个参数: 9 参数的类型:<class 'tuple'> 10 第二个参数是: i 11 ''' 12 test("小甲鱼", 123, 3.14) 13 ''' 14 有 3 个参数: 15 参数的类型:<class 'tuple'> 16 第二个参数是: 123 17 '''
收集参数:将传入的参数打包成一个元组。
注意: 如果收集参数后边还需要指定其他参数,在调用函数时候就应该使用关键字参数来指定,否则Python就都会把你的实参列入收集参数的范畴
# 收集参数的注意点: def test(*args, extra): print("收集参数是:", args) print("位置参数是:", extra) ''' test(1,2,3,4,5,6,7,8) Traceback (most recent call last): File "E:/PycharmProjects/s14/day3/func_02.py", line 23, in <module> test(1,2,3,4,5,6,7,8) TypeError: test() missing 1 required keyword-only argument: 'extra' ''' #正确调用姿势 test(1,2,3,4,5, extra = 8) # 收集参数是: (1, 2, 3, 4, 5) # 位置参数是: 8
建议:如果参数中带有收集参数,那么可将其他参数设置为默认参数,这样不容易出错:
# 建议: def test(*args, extra=8): print("收集参数是:", args) print("位置参数是:", extra) test(1,2,3,4,5) #收集参数是: (1, 2, 3, 4, 5) #位置参数是: 8
星号(*)其实既可以打包又可以解包
解包:举个例子,加入你需要将一个列表a传入test参数的收集参数*args中,那么调用test(a)时便会出错,此时需要在a前边加上个(*)表示实参需要"解包"后才能使用
# 解包: def test(*args): print("有 %d 个参数:" % len(args)) print("第二个参数是:", args[1]) a = [1,2,3,4,5,6,7,8] #错误姿势 test(a) ''' 有 1 个参数: Traceback (most recent call last): File "E:/PycharmProjects/s14/day3/func_02.py", line 49, in <module> test(a) File "E:/PycharmProjects/s14/day3/func_02.py", line 47, in test print("第二个参数是:", args[1]) IndexError: tuple index out of range ''' #正确姿势: test(*a) #有 8 个参数: #第二个参数是: 2
Python还有另一种收集方式,就是用两个星号(**)表示。两个星号的收集参数表示为将参数打包成字典的形式。
即:**kwargs
# **演示: def test(**kwargs): # **kwargs 会把多传入的参数变成一个dict形式 print(kwargs) test(name="james", age=25, sex="man") # {'sex': 'man', 'name': 'james', 'age': 25}
*args:接收多个位置参数,转换成元组的形式
**kwargs:接收多个关键字参数,转换成字典的形式
局部变量
变量的作用域就是平时所说的变量可见性,编程语言都有局部变量和全局变量之分,分析以下代码:
1 #分析:在函数discounts()中,两个参数是price和rate,还有一个final_price,它们都是函数中的局部变量 2 def discounts(price, rate): 3 final_price = price * rate 4 return final_price 5 6 old_price = float(input("请输入原价:")) 7 rate = float(input("请输入折扣率:")) 8 new_price = discounts(old_price, rate) 9 print("打折后的价格是:%d" % new_price)
1 # 函数外访问局部变量 2 def discounts(price, rate): 3 final_price = price * rate 4 return final_price 5 6 old_price = float(input("请输入原价:")) 7 rate = float(input("请输入折扣率:")) 8 new_price = discounts(old_price, rate) 9 print("打折后的价格是:%d" % new_price) 10 print("这里试图打印局部变量final_price的值:", final_price) 11 12 ''' 13 请输入原价:80 14 请输入折扣率:0.75 15 打折后的价格是:60 16 Traceback (most recent call last): 17 File "E:/PycharmProjects/s14/day3/func_03.py", line 11, in <module> 18 print("这里试图打印局部变量final_price的值:", final_price) 19 NameError: name 'final_price' is not defined 20 ''' 21 # 错误原因:final_price没有被定义过,Python找不到final_price这个变量, 22 # 这是因为final_price只是一个局部变量,它的作用范围只在它的地盘上--discounts()函数的定义范围内
全局变量
与局部变量相对的是全局变量,程序中old_price、new_price、rate都是在函数外边定义的,它们都是全局变量,全局变量有更大的作用域,例如在函数中可以访问它们:
1 def discounts(price, rate): 2 final_price = price * rate 3 print("这里试图打印全局变量old_price的值:", old_price) 4 return final_price 5 6 old_price = float(input("请输入原价:")) 7 rate = float(input("请输入折扣率:")) 8 new_price = discounts(old_price, rate) 9 print("打折后的价格是:%d" % new_price) 10 ''' 11 请输入原价:80 12 请输入折扣率:0.75 13 这里试图打印全局变量old_price的值: 80.0 14 打折后的价格是:60 15 '''
建议:函数中无法直接修改全局变量,可用global关键字,但最好不要在函数中修改全局变量的值(参考P58)
参考博客:http://www.cnblogs.com/alex3714/articles/5740985.html

浙公网安备 33010602011771号