Python基础03 :函数、递归、内置函数

1.函数基本语法及特性

定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

特性:

  1. 减少重复代码
  2. 使程序变的可扩展
  3. 使程序变得易维护

语法定义

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

 

posted @ 2017-02-05 11:02  是在下输了。  阅读(137)  评论(0)    收藏  举报