Python基础教程(六):函数+练习题

一、函数的定义

1. 函数的定义:实现【特定功能】的代码块。

2. 函数的作用:

        a、简化代码

        b、提高代码重用性

        c、便于维护和修改

        d、提高代码的可扩展性

3. 函数的三要素:

功能

len(),max(),sum()
参数 list.clear(),list.append(‘hello')
返回值 list.sort(),nlist = sorted(list)

4. 函数定义的语法格式:

def max(a, b):
    if a > b:
        return a
    else:
        return b

# 函数可以输入参数,并设置返回值
# 使用 def 关键字定义函数
# a、b为函数参数
# return 关键字设置返回值

5. 函数的分类

        a、从定义角度:内置函数(别人写好的,可直接用);自定义函数;

        b、从参数角度:无参函数;有参函数;

        c、从返回值角度:无返函数None;有返函数;

6. 函数的调用/使用

        a. 无返函数:函数名()

        b. 有返函数:

                方法1:print(函数名())

def my_fun():
    print("这是我的函数。")

print(my_fun)
# 【输出结果】:<function my_fun at 0x1008b72e0>,说明函数名是一个内存地址


my_fun()    # 无返函数直接调用
# 【输出结果】:这是我的函数。

                方法2:变量名 = 函数名()

def num_fun():
    return 100

print(num_fun())    # 有返函数,输出调用

ret = num_fun()     # 有返函数,使用变量接收调用
print(ret)

#【运行结果】:
# 100
# 100

        

二、函数的参数传递

        2.1: 形参和实参

                形参:函数定义时的参数,没有实际意义

def fun(a)
def fun(a:int)
def fun(*a)
def fun(**a)

                实参:函数调用/使用时的参数,有实际意义

fun(1, 'a', 13.14, True, [1,2], (3,4), {1,2})
fun(len(s))

        2.2:函数在进行参数传递的时候,分为:

                位置参数、关键字参数、默认参数、位置不定长参数、关键字不定长参数。

                a. 位置参数:

                        传递参数时应该和“定义时的参数”保持位置和数量一一对应。

# 【示例】位置参数
def fun(a, b, c):
    print(a, b, c)

fun(1, 2, 3)
#【运行结果】:
# 1 2 3

                b. 关键字参数:

                        调用函数传递参数时,按照“参数名=值”的方式;

                        传参的顺序可以和定义参数的顺序不一致。

# 【示例】关键字参数
def fun(name, age, sex):
    print(name, age, sex)

fun(name='张三', age=18, sex='男')
fun(age=18, sex='男', name='张三')
#【运行结果】:
# 张三 18 男
# 张三 18 男

                c. 默认参数:

                        在函数定义时,给参数设置默认值;

                        则函数调用时,若不传参就是用默认值,若传参就是用传参的值。

# 【示例】默认参数
def fun(name='张三', age=18, sex='男'):
    print(name, age, sex)

fun()
fun('李四')
fun(age=66)
fun('小明', 30)
fun('小华', 23, '女')
#【运行结果】:
# 张三 18 男
# 李四 18 男
# 张三 66 男
# 小明 30 男
# 小华 23 女

                d. 位置不定长参数:

                        在定义函数时参数名前加 * ,也就是def fun( *args );

                        在传参的时候就可以传若干个位置参数,并将参数打包成“元组”。

# 【示例】位置不定长参数
# 问:在一个函数中,位置不定长参数,可以有两个吗?
# 答:不允许
# 问:一旦定义了位置不定长参数,是不是就不可以定义其他参数了呢?
# 答:可以定义其他参数,但是传参时必须是关键字参数
def test1(*num):
    print(num)
test1(1)
test1(1, 2)
test1(1, 2, 3, 4, 5, 6)
#【运行结果】:
# (1,)
# (1, 2)
# (1, 2, 3, 4, 5, 6)


def test2(*num, a, b):
    print(num)
    print(a)
    print(b)
test2(1, 2, 3, 4, a=5, b=6)
#【运行结果】:
# (1, 2, 3, 4)
# 5
# 6


def test3(a, b, *num):
    print(a)
    print(b)
    print(num)
test3(1, 2, 3, 4, 5, 6, 7)
#【运行结果】:
# 1
# 2
# (3, 4, 5, 6, 7)


def test4(a, *num, b):
    print(a)
    print(num)
    print(b)
test4(1, 2, 3, 4, 5, b=66)
#【运行结果】:
# 1
# (2, 3, 4, 5)
# 66

                e. 关键字不定长参数:

                        在定义函数参数名前加 ** ,也就是 def fun( **kwargs );

                        在传参的时候就可以传若干个关键字参数,并将参数打包成“字典”。

# 【示例】关键字不定长参数
def fun(**kwargs):
    print(kwargs)

fun(a=12, b=13, c=15)
fun(姓名='张三', 年龄=18, 性别='男')
#【运行结果】:
# {'a': 12, 'b': 13, 'c': 15}
# {'姓名': '张三', '年龄': 18, '性别': '男'}

        2.3:小练习

# 定义函数,参数为位置可变长参数;
# 请将传入的所有实参,按照升序输出;

def up(*num):
    print(sorted(num))

up(2, 5, 8, 1, 4, 9, 7, 15, 12)

# 【运行结果】:
# [1, 2, 4, 5, 7, 8, 9, 12, 15]
# 定义函数,参数为关键字可变长参数,请将其中HuaHua的身高修改为160;
# 打印出所有身高不足180的学生姓名;
# 使用fun(XiaoMing=155, XiaoHong=171, XiaoHei=192, HuaHua=2333)调用测试;

def fun(**students):
    if 'HuaHua' in students:
        students['HuaHua'] = 160
    print(students)

    for name in students.keys():
        if students[name] < 180:
            print(name)

fun(XiaoMing=155, XiaoHong=171, XiaoHei=192, HuaHua=2333)

#【运行结果】:
# {'XiaoMing': 155, 'XiaoHong': 171, 'XiaoHei': 192, 'HuaHua': 160}
# XiaoMing
# XiaoHong
# HuaHua

三、函数的返回值

        1、如果函数的运行结果想在函数外使用,就需要设置返回值。

        2、使用关键字 return 进行返回。

        3、return 可以在函数中出现多次,但是只执行 1 次,遇见 return 返回值并结束函数。

        4、Python中的 return 可以返回一个值或多个值,将返回的多个值打包成一个元组。

def fun(*num):
    my_sum = 0
    for i in num:
        my_sum += i
    return my_sum

ret = fun(3, 7, 2, 9, 8)
print(ret)
print(type(ret))

#【运行结果】:
# 29
# <class 'int'>
def fun1(*num):
    my_sum = 0
    even_sum = 0
    odd_sum = 0
    for i in num:
        my_sum += i
        if i%2==0:
            even_sum += i
        else:
            odd_sum += i
    return my_sum, even_sum, odd_sum

res = fun1(2, 8, 7, 3, 11, 10)
print(res)
print(type(res))

a, b, c = fun1(2, 8, 7, 3, 11, 10)
print(a, b, c)

#【运行结果】:
# (41, 20, 21)
# <class 'tuple'>
# 41 20 21

        3.1:简单函数小练习

# 1、定义函数,无参无返,可求出200以内所有包含7的数字;
def num():
    num_list = []
    list_7 = []
    for i in range(200):
        num_list.append(str(i))

    for j in num_list:
        if "7" in j:
            list_7.append(j)
    print(list_7)

num()

#【运行结果】:
# ['7', '17', '27', '37', '47', '57', '67', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '87', '97', '107', '117', '127', '137', '147', '157', '167', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '187', '197']
# 2、定义函数,无参有返,可返回200-300所有偶数组成的数列;
def num_2():
    list_23 = []
    for i in range(200, 300+1):
        if i % 2 == 0:
            list_23.append(i)

    print(list_23)

num_2()

#【运行结果】:
# [200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, 300]
# 3、定义函数,有参无返,可接收任意一个字符串,并计算该字符串有几个字符;
def num_3(s):
    print(f"你输入的字符串总计 {len(s)} 个字符。")

len_str = input("请输入一个字符串:")
num_3(len_str)

#【运行结果】:
# 请输入一个字符串:abcdefghijklmnopqrstuvwxyz
# 你输入的字符串总计 26 个字符。
# 4、定义函数,有参有返,可接收任意一个字符串,对其进行去重,返回去重后的集合;
def set_str(s):
    set_s = set(s)
    print(set_s)

st = input("请输入一个字符串:")
set_str(st)

#【运行结果】:
# 请输入一个字符串:hello world i am adrian!
# {' ', 'e', 'n', 'm', 'r', 'i', 'h', 'l', 'd', '!', 'w', 'a', 'o'}
# 5、定义函数,可接收个数字列表,并返回其中的最大和最小值;
def fun6(l):
    max_i = l[0]
    min_i = l[0]
    for i in l:
        if max_i < i:
            max_i = i
        if min_i > i:
            min_i = i

    return max_i, min_i

list_6 = [8, 5, 9, 74, 23, 15, 1, 3, 6]
ls_max, ls_min = fun6(list_6)
print(f"最大值为:{ls_max}")
print(f"最小值为:{ls_min}")

#【运行结果】:
# 最大值为:74
# 最小值为:1
# 6、定义函数,参数为关键字可变长参数,请计算他们的平均身高,
# 测试数据:(xiaoming=’178cm’,xiaobai=’182cm’,xiaohong=’166cm’,xiaohei=’174cm’)
def fun_11(**students):
    sum_h = 0
    sn = 0
    for i in students.values():
        sum_h += int(i.split('cm')[0])
        sn += 1
    return sum_h / sn

ret = fun_11(xiaoming='178cm',xiaobai='182cm',xiaohong='166cm',xiaohei='174cm')
print(f"平均身高为:{ret} cm")

#【运行结果】:
# 平均身高为:175.0 cm

四、递归函数

        4.1:递归函数:就是自己调用自己的函数。

        4.2:递归的思想:把一个大规模问题分解成相似的小规模问题;

                              再将小规模问题分解成相似的小小规模问题。。。

# 要求定义一个函数,实现输出n遍"我爱python"
def fun(n:int):
    while True:
        print("我爱python")
        n -= 1
        if(n==0):
            break

fun(10)

# #【运行结果】:
# # 我爱python
# # 我爱python
# # 我爱python
# # 我爱python
# # 我爱python
# # 我爱python
# # 我爱python
# # 我爱python
# # 我爱python
# # 我爱python


# 要求定义一个递归函数,实现输出n遍"我爱python"
def rec(n:int):
    if n==0:
        return
    else:
        print(f"{n} 我爱python")
        rec(n-1)
        
rec(10)

#【运行结果】:
# 10 我爱python
# 9 我爱python
# 8 我爱python
# 7 我爱python
# 6 我爱python
# 5 我爱python
# 4 我爱python
# 3 我爱python
# 2 我爱python
# 1 我爱python

        对比发现:“循环”和“递归”很相似,基本上他们两个可以相互转换。

                1、大多数情况下,循环的效率、性能更好一些;

                2、循环代码容易书写,阅读性差;

                3、递归代码写起来稍难,阅读性好。

        4.3:递归函数有三要素:

边界条件 / 基线条件

跳出 / 结束 递归的条件

递归返回段

满足结束条件时,返回

递归返回段

不满足结束条件时,前进 / 继续递归

        4.4:小练习

# 定义一个递归函数,求n的阶乘;
# 阶乘:就是累乘,从1累乘到本身,或者从本身累乘到1;
# 比如:5! = 1*2*3*4*5 = 5*4*3*2*1
def rec(n):
    if n==1:
        return 1
    else:
        return n * rec(n-1)

n = 5
print(f"5!=1*2*3*4*5={rec(n)}")

#【运行结果】:
# 5!=1*2*3*4*5= 120

五、函数中变量的作用域

        变量的作用域:是指变量能起作用的范围;

                                 根据作用范围大小不同,分为“全局变量”和“局部变量”。

        5.1:全局变量:定义在函数外,作用范围是整个程序;

                                   程序结束时,全局变量声明周期结束。

# 全局变量都能用
quanju = 10

def fun1():
    print(quanju)

def fun2():
    print(quanju)

print(quanju)
fun1()
fun2()

#【运行结果】:
# 10
# 10
# 10

        5.2:局部变量:定义在函数代码块里或者函数的参数里;

                                   作用范围是整个函数,函数执行结束时局部变量生命周期结束。

# 局部变量只能在该函数内使用
def fun1():
    a = 10
    print(a)

def fun2():
    print(f"fun1函数中的{a}")

fun1()

#【运行结果】:
# 10

fun2()
#【运行结果】:
# print(f"fun1函数中的{a}") 报错!
# NameError: name 'a' is not defined

        5.3:global关键字的使用

# 若想在函数外,使用该函数的局部变量;
# 使用 global 关键字将该变量修饰为全局变量。

def fun1():
    global a
    a = 10
    print(a)

def fun2():
    print(f"fun1函数中的:{a}")

fun1()
fun2()
print(f"fun1函数中的:{a}")

#【运行结果】:
# 10
# fun1函数中的:10
# fun1函数中的:10

        5.4:局部变量与全局变量的重名

# 从以下代码可以看到,局部变量可以和全局变量重名;
# 但是:局部变量覆盖全局变量(遵循就近原则);

a = 100     #全局变量
def fun():
    a = 200     # 局部变量
    print(a)

print(a)
fun()

#【运行结果】:
# 100
# 200

六、函数嵌套

        函数嵌套:在一个函数的内部,还嵌套定义了另外一个函数。

        外部的我们称之为“外函数”,内部的我们称之为“内函数”。

def out_fun():
    print("外函数")
    def in_fun():
        print("内函数")
    in_fun()

out_fun()

#【运行结果】:
# 外函数
# 内函数
def out_fun():
    print("外函数")
    def in_fun():
        print("内函数")
    return in_fun()

out_fun()

# #【运行结果】:
# 外函数
# 内函数
def out_fun():
    print("外函数")
    def in_fun():
        print("内函数")
    return in_fun

out_fun()()

#【运行结果】:
# 外函数
# 内函数

        6.1:global 和 nonlocal

def out_fun():
    def in_fun():
        global x
        x = 100
        print(f"内函数里面的{x}")
    in_fun()
    print(f"这是外函数,想使用内函数里的{x}")

out_fun()

#【运行结果】:
# 内函数里面的100
# 这是外函数,想使用内函数里的100
def out_fun():
    x = 666
    def in_fun():
        nonlocal x
        x = 100
        print(f"内函数里面的{x}")
    in_fun()
    print(f"这是外函数,想使用内函数里的{x}")

out_fun()

#【运行结果】:
# 内函数里面的100
# 这是外函数,想使用内函数里的100

        6.2:函数嵌套例子对比

x = 100
def out_fun():
    # global x
    x = 200
    def in_fun():
        # global x
        x = 300
        print(f"内函数中输出{x}")
    in_fun()
    print(f"外函数中输出{x}")

out_fun()
print(f"函数外输出{x}")

#【运行结果】:
# 内函数中输出300
# 外函数中输出200
# 函数外输出100
x = 100
def out_fun():
    global x
    x = 200
    def in_fun():
        global x
        x = 300
        print(f"内函数中输出{x}")
    in_fun()
    print(f"外函数中输出{x}")

out_fun()
print(f"函数外输出{x}")

#【运行结果】:
# 内函数中输出300
# 外函数中输出300
# 函数外输出300

        通过上面的例子可以发现:内函数局部变量 > 外函数局部变量 > 全局变量

        对比 global 和 nonlocal:

                 1. global 修饰全局变量;

                2. nonlocal 修饰该函数上一层的局部变量;

七、闭包函数

        7.1:什么是闭包?

                如果内函数中使用了外函数的局部变量,并且外函数把内函数返回的过程就叫闭包。

                形成闭包的条件:

                        1. 函数嵌套

                        2. 将内函数作为返回值返回

                        3. 内函数必须使用外函数的局部变量

        7.2:示例代码

# out_fun() 有参有返回函数
# in_fun()  有参有返回函数

def out_fun(x):
    def in_fun(y):
        return y ** x
    return in_fun

print(out_fun(2)(3))

ret = out_fun(5)
print(ret(2))

#【运行结果】:
# 9
# 32
# out_fun() 无参有返回函数
# in_fun()  无参有返回函数

def out_fun():
    x = 100
    def in_fun():
        return x + 666
    return in_fun

print(out_fun()())

#【运行结果】:
# 766
# out_fun() 无参有返回函数
# in_fun()  无参有返回函数

def out_fun():
    x = 100
    def in_fun():
        return x + 666
    return in_fun()

print(out_fun())

#【运行结果】:
# 766

作者:飞翔的煤气罐boom

物联沃分享整理
物联沃-IOTWORD物联网 » Python基础教程(六):函数+练习题

发表回复