第5章 、函数

一、函数

1.函数的概括

函数是组织好的、实现单一功能或相关联功能的代码段

函数式编程具有的优点:

1、将程序模块化,既减少了冗余代码,又让程序结构更为清晰
2、提高开发人员的编程效率
3、方便后期的维护与扩展

2.定义函数:

   函数代码块使用关键字def来定义函数

def 函数名 ([参数列表]):
         [" " "文档字符串" " "]
         函数体
              [return语句]
def: 标记函数的开始
函数名:函数的唯一标识
[参数列表]: 传入函数中的数据,可以包含一个或多个参数,也可以为空
函数体实现函数功能的具体代码
[return语句]: 返回函数的处理结果给调用方,标志着函数的结束,若函数没有返回值,可以省略

例如,定义一个计算两个数之和的函数,代码如下:

#无参数
def add():
    result = 11 + 22
    print(result)

#有参数
def add_modify(a, b):
    result = a + b
    print(result)

3.调用函数

函数在定义完成后不会立刻执行,直到被程序调用时才会执行

语法格式:

函数名([参数列表])

例如:

add()

add_modify(10, 20

调用过程: 

 1. 程序在调用函数的位置暂停执行。

2. 将数据传递给函数参数。

3. 执行函数体中的语句。

4. 程序回到暂停处继续执行

函数内部也可以调用其他函数,这被称为函数的嵌套调用

def add_modify(a, b):
    result = a + b
    add()   	
    print(result)
add_modify(10, 20)   #嵌套调用函数add()

调用过程:

4.函数参数的传递

函数的参数传递是指将实际参数传递给形式参数的过程

函数参数的传递可以分为位置参数传递、关键字参数传递、默认参数传递、参数的打包与解包以及混合传递

函数在被调用时会将实参按照相应的位置依次传递给形参,也就是说将第一个实参传递给第一个形参,将第二个实参传递给第二个形参

def get_max(a, b):
    if a > b:
        print(a,"是较大的值!")
    else:
        print(b,"是较大的值!")
get_max(8, 5)   #a=8   b=5   8是较大的值
 

 

5.关键字参数的传递

关键字参数的传递是通过“形参=实参”的格式将实参与形参相关联,将实参按照相应的关键字传递给形参,例如:

def connect(ip, port):
    print(f"设备{ip}:{port}连接!")
connect(ip="127.0.0.1", port=8080  

使用符号“/”来定部分形参只接收采用位置传递方式的实参

例如

def func(a, b, /, c):
    print(a, b, c)

 # 错误的调用方式

 func(a=10, 20, 30)  

 func(10, b=20, 30)

# 正确的调用方式

func(10, 20, c=30)

 6.默认参数的传递

函数在定义时可以指定形参的默认值

def connect(ip, port=8080):      #定义
    print(f"设备{ip}:{port}连接!")
connect(ip="127.0.0.1")
connect(ip="127.0.0.1", port=3306)   #调用

结果:                

                设备127.0.0.1:8080连接!

                设备127.0.0.1:3306连接!

7.参数的打包与解包

7.1.打包

如果函数在定义时无法确定需要接收多少个数据,那么可以在定义函数时为形参添加*”或“**

*—— 接收以元组形式打包的多个值

def test(*args):
    print(args)
test(11, 22, 33, 44, 55)

结果:

(11, 22, 33, 44, 55)

**—— 接收以字典形式打包的多个值

def test(**kwargs):
    print(kwargs)
test(a=11, b=22, c=33, d=44, e=55)

结果:

{'a': 11, 'b': 22, 'c': 33, 'd': 44, 'e': 55}

7.2.解包

实参是 元组   →   可以使用“ * 拆分 成多个值  →  按 位置 参数 给形参
实参是 字典    →    可以使用“ ** 拆分 成多个键值对    →    关键字 参数 形参
def test(a, b, c, d, e):
    print(a, b, c, d, e)
nums = (11, 22, 33, 44, 55)
test(*nums)

结果:

{'a': 11, 'b': 22, 'c': 311 22 33 44 553, 'd': 44, 'e': 55}

def test(a, b, c, d, e):
    print(a, b, c, d, e)
nums = {"a":11, "b":22, "c":33, "d":44, "e":55}
test(**nums)

结果:11 22 33 44 55

8.混合传递

 混合使用需要遵循一定的规则,具体规则如下:

1、优先按位置参数传递的方式。

2、然后按关键字参数传递的方式。

3、之后按默认参数传递的方式。

 4、最后按打包传递的方式

在定义函数时:

带有默认值的参数必须位于普通参数之后
带有“ * ”标识的参数必须位于带有默认值的参数之后

        带有“**”标识的参数必须位于带有“*”标识的参数之后

def test(a, b, c=33, *args, **kwargs):
print(a, b, c, args, kwargs)
test(1, 2)
test(1, 2, 3)
test(1, 2, 3, 4)
test(1, 2, 3, 4, e=5)

结果:

1 2 33 () {}

1 2 3 () {}

1 2 3 (4,) {}

1 2 3 (4,) {'e': 5}

8.函数的返回值

return语句会在函数结束时将数据返回给程序,同时让程序回到函数被调用的位置继续执行

def filter_sensitive_words(words):
    if "山寨" in words:
        new_words = words.replace("山寨", "**")
        return new_words
result = filter_sensitive_words("这个手机是山寨版吧!")
print(result)

 结果:

9. 函数的返回值

如果函数使用return语句返回了多个值,那么这些值将被保存到元组中

def move(x, y, step):
    nx = x + step
    ny = y - step
    return nx, ny     # 使用return语句返回多个值
result = move(100, 100, 60)  	
print(result)

结果:

(160,40)

10.变量作用域

变量并非在程序的任意位置都可以被访问,其访问权限取决于变量定义的位置其所处的有效范围称为变量的作用域

11.局部变量和全局变量

根据作用域的不同,变量可以划分为局部变量和全局变量

11.1.局部变量

函数内部定义的变量,只能在函数内部被使用

函数执行结束之后局部变量会被释放,此时无法再进行访问

def test_one():
    number = 10    	              # 局部变量
    print(number) 	              # 函数内部访问局部变量
test_one()
print(number)     	              # 函数外部访问局部变量

不同函数内部可以包含同名局部变量,这些局部变量的关系类似于不同目录下同名文件的关系,它们相互独立,互不影响

def test_one():
    number = 10      
    print(number)             # 访问test_one()函数的局部变量number
def test_two():
    number = 20
    print(number)             # 访问test_two()函数的局部变量number
test_one()
test_two()

结果:

 11.2.全局变量

全局变量可以在整个程序范围内起作用,它不会受到函数范围的影响

number = 10         							# 全局变量
def test_one():
    print(number)   							# 函数内部访问全局变量
test_one()
print(number)       

结果:

  全局变量在函数内部只能访问,而无法直接修改,函数内部只能访问全局变量,而无法直接修改全局变量

 12.global和nonlocal关键字

12.1.global关键字

使用global关键字可以将局部变量声明为全局变量

number = 10                    # 定义全局变量
def test_one():
    global number              # 使用global声明变量number为全局变量
    number += 1
    print(number)
test_one()
print(number)

结果:

  12.2.nonlocal关键字

使用nonlocal关键字可以在局部作用域中修改嵌套作用域中定义的变量

def test():
    number = 10
    def test_in():
        nonlocal number
        number = 20
    test_in()
    print(number)
test()

 结果:

 13.递归函数

函数在定义时可以直接或间接地调用其他函数。若函数内部调用了自身,则这个函数被称为递归函数

递归函数在定义时需要满足两个基本条件:一个是递归公式,另一个是边界条件:

递归公式是求解原问题或相似的子问题的结构

边界条件是最小化的子问题,也是递归终止的条件

递归函数的执行可以分为以下两个阶段:

1.递推:递归本次的执行都基于上一次的运算结果。

2.回溯:遇到终止条件时,则沿着递推往回一级一级地把值返回来

递归函数的一般定义格式:

def函数名([参数列表])

          if 边界条件:

                  rerun 结果

          else:

                return 递归公式

阶乘:

n! = 1 * 2 * 3 * … * n,可以分为以下两种情况:

1. 当n=1时,所得的结果为1。

2. 当n>1时,所得的结果为n*(n-1)!

def func(num):
     if num == 1: 
         return 1
     else:
         return num * func(num - 1)
num = int(input("请输入一个整数:"))
result = func(num)
print("5!=%d"%result)

结果:

 

14.匿名函数

lambda关键字定义匿名函数,它的语法格式如下:

lambda <形式参数列表> :<表达式>

匿名函数与普通函数的主要区别如下:

        1.普通函数在定义时有名称,而匿名函数没有名称;

        2.普通函数的函数体中包含有多条语句,而匿名函数的函数体只能是一个表达式;

        3.普通函数可以实现比较复杂的功能,而匿名函数可实现的功能比较简单;

        4.普通函数能被其他程序使用,而匿名函数不能被其他程序使用

定义好的匿名函数不能直接使用,最好使用一个变量保存它,以便后期可以随时使用这个函数

# 定义匿名函数,并将它返回的函数对象赋值给变量temp
temp = lambda x : pow(x, 2) 
temp(10) 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值