Python基础学习之 函数用法详解

1. 函数的定义

定义一个函数,需要以下几步:

  1. 第一步:函数代码块第一句:def + 函数名称 + 圆括号 (形参) + :,举例:
  2. 第二步:在函数体开始的时候,可以书写帮助文档;
  3. 第三步:函数体,缩进一行进行书写;完成自己想要的功能;
  4. 第四步:返回值(return 语句),返回一个值给调用方;
  5. 第五步:可以直接使用函数名称调用函数;

举例如下:

def add(a, b):   # 第一步:这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
    '''    
    :param a: 第一个数字
    :param b: 第二个数字
    :return: 返回两个值的和
    ''' 
    # 第二步:上面是函数的帮助文档,使用三引号进行定义; 
    c = a + b
    # 第三步:函数体
    return c    # 第四步:返回值语句

print(add(3,5))    # 第五步:函数调用

2. 函数的调用

2.1 函数的一般调用

当函数定义完成,可以直接通过函数名称调用函数;在调用时,需要给对应位置传入参数;参考上例中的第五步;

2.2 函数的递归调用

递归调用就是在函数内部调用自己(自己调用自己),通常用它来计算阶乘,累加等; 注意:

  1. 必须有一个明确的结束条件,即调用到最后,需要有一个确定的值;     if n ==0,(不能一直调用自己,如果没有可能会造成死循环)
  2. 递归参数必须向默认的结果收敛,即:次进入更深一层递归时,问题规模相比上次递归都应有所减少;     func(n-1)

举两个例子: 1. 递归求和; 2. 递归求阶乘; 参考下面代码:

# 递归求和 
def func(n):
    sum = 0
    if n == 0:
        return 0
    else:
        return n + func(n-1)

print(func(100))

# 递归求阶乘 
def func(n):
    if n == 0:
        return 1
    else:
        return n * func(n - 1)

print(func(10))

3. 函数的参数传递

3.0 实参&形参

函数的参数,分为形参和实参。简单的说:形参就是函数接收的参数,而实参就是你实际传入的参数。 形参:形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。
实参:实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量。在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。

实参 & 形参举例:

# 实参 & 形参
def add(a, b):   # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
    c = a + b
    return c

print(add(3,5))    # 这里的3,5 就是 a,b 对应的实参;输出:8

3.1 默认参数

默认参数就是在定义形参的时候,给函数默认赋一个值;例如在上述的例子中,我们可以在定义函数的时候,给形参赋默认值;这样的话,调用函数时如果未指定实参,将用默认值代替实参;

def add(a = 2, b = 3):   # 这里 a = 2, b = 3 就是默认赋值
    c = a + b
    return c

print(add(3,5))    # 这里的3,5 就是 a,b 对应的实参;输出:8
print(add())   # 这里未指定值,就用默认值进行计算;输出:5

3.2 必须参数

必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。 当函数定义时,定义了形参,并且未赋值默认值时,我们在调用参数时,就必须传入参数;传入的参数,位置,数量,数据类型都需要满足条件,才可以调用成功;

3.3 关键字参数

函数调用使用关键字参数来传入实参,使用关键字参数传参时,允许函数调用时参数的顺序与声明时不一致。举例:

def op(a = 2, b = 3):   # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
    '''
    :param a: 第一个数字
    :param b: 第二个数字
    :return: 返回两个值的和
    '''
    c = a + b
    d = a - b
    e = a * b
    f=(a,b,c,d,e)
    return f

a,b,c,d,e =op(b=15,a=20)   # 这里使用关键字传参,改变了参数的位置
print('两个数 a =%s,b=%s,它们的和是%s,差是%s,乘积是%s;'%(a,b,c,d,e))
# 输出:两个数 a =20,b=15,它们的和是35,差是5,乘积是300;

3.4 不定长参数 (*args、**kwargs含义)

python自定义函数中有两中不定长参数,第一种是*name,第二种是**name。

3.4.1 一个星号 * 的使用(*args)

加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。

# 例一:数字
def add2(*args):
    result = 0
    for i in args:
        result += i
    return result


print(add2(1, 2, 3))    # 输出:6
print(add2(1, 2, 3, 4, 5))    # 输出:15

# 例二:字符串
def show_str(a,b,*args):
    print(a)
    print(b)
    print(args)

show_str('双截棍','听妈妈的话','以父之名','夜曲','夜的第七章')

# 输出:
# 双截棍
# 听妈妈的话
# ('以父之名', '夜曲', '夜的第七章')


# 例三:
def show_list(a,*args):
    print(a)
    print(args)

show_list([1,2],[2,3,4],[4,5])    
# 输出:
# [1, 2]
# ([2, 3, 4], [4, 5]) 
3.4.2 两个星号 ** 的使用 (**kwargs含义)

数字,字符串,列表都可以使用 * 进行不定长传参; 字典需要加两个星号 ** 的参数才可以不定长传参。

def show_dic(**kwargs):
    print(kwargs)

# 引用方式一:
show_dic(Jay='爱在西元前',JJ='一千年以后') # 直接传入字典

# 引用方式二:
dic = {'Jay':'爱在西元前','JJ':'一千年以后'}
dic2 = {'蔡':'情人'}
show_dic(**dic,**dic2)    # 传入字典变量,需要使用 **+变量名 这种方式来传入;输出:{'Jay': '爱在西元前', 'JJ': '一千年以后', '蔡': '情人'}

4. 返回值

4.1 返回值的特点

  1. 每个函数都有返回值,如果没有在函数里面指定返回值的话,在python里面函数执行完之后,默认会返回一个None;
  2. 函数也可以有多个返回值,如果有多个返回值的话,会把返回值都放到一个元组中,返回的是一个元组。
  3. 函数中的返回值使用return,函数在遇到return就立即结束。

4.2 没有返回值

每个函数都有返回值,如果没有在函数里面指定返回值的话,在python里面函数执行完之后,默认会返回一个None;

# 没有返回值
import datetime

def show_time():
    print(datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'))

show_time()  # 输出:2020-09-29 10:43:20

4.3 一个返回值

# 有一个返回值
import datetime

def get_time():
    a = datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S')
    return a  # 返回时间

print(get_time())  # 输出:2020-09-29 10:43:20

4.4 多个返回值

函数也可以有多个返回值,如果有多个返回值的话,会把返回值都放到一个元组中,返回的是一个元组。

# 多个返回值
def op(a=2, b=3):  # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
    '''
    :param a: 第一个数字
    :param b: 第二个数字
    :return: 返回两个值的和
    '''
    c = a + b
    d = a - b
    e = a * b
    return a, b, c, d, e  # 也可以写成:return (a,b,c,d,e)

a, b, c, d, e = op(20, 15)
print('两个数 a =%s,b=%s,它们的和是%s,差是%s,乘积是%s;' % (a, b, c, d, e))
# 输出: 两个数 a =20,b=15,它们的和是35,差是5,乘积是300;

5. 局部变量 & 全局变量

  1. 局部变量意思就是在局部的变量作用域生效;变量的作用域外,变量就失效了。
  2. 全局变量意思就是在整个程序里面都生效的;一般全局变量在程序开始时定义。
  3. 全局变量如果要在函数中修改的话,需要加global关键字声明;但是list、字典和集合,不需要加global关键字声明,直接就可以修改。
  4. 任何函数都可以修改,所以尽量少用全局变量,原因1不够安全。原因2全局变量一直占用内存。
# 字符串的 局部变量 & 全局变量
a = '我和我的祖国'

def name1():    # name1() 函数里给 a 赋值了,但是这里的赋值不会影响全局变量中的 a;
    a = '摔跤吧!爸爸'   # 局部变量的 a 赋值了'摔跤吧!爸爸',全部变量的 a 依然是'我和我的祖国';
    print(a)

def name2():   # name2() 用来打印全局变量 a ;
    print(a)

def name3():   # name3() 中在 a 赋值前,用 global 声明了a, 这是 再给 a 赋值就会改变全部变量的 a;
    global a
    a = '无双'
    print(a)

name1()    # 输出:摔跤吧!爸爸
name2()    # 输出:我和我的祖国
name3()    # 输出:无双
name2()    # 输出:无双  # 这时全局变量中的 a 已经被改变了;


# 列表的局部变量 & 全局变量
a = [1,2,3,4,5]

def list1():     # 函数中未使用global声明,但是可以改变全局变量的值;
    a[1]='变身!'
    print(a)

list1()     # 调用函数;输出:[1, '变身!', 3, 4, 5]
print(a)    # 输出:[1, '变身!', 3, 4, 5]

6. 匿名函数

在实际编程中,有时函数只需要完成很简单的功能,这时就可以使用匿名函数;理解匿名函数的关键:功能简单,只能是一句话函数;举例:以下两种方法能完成的功能是完全一样的,只是匿名函数更简单一些;

# 正常定义函数
def add(a, b):  # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
    c = a + b
    return c
 
print(add(2,3))   # 输出:5

# 使用匿名函数
add_1 = lambda a,b:a+b
print(add_1(2,3))    # 输出:5

在这里插入图片描述 更详细的匿名函数的用法,请参考 python 之 匿名函数