Python中的函数

程序中反复执行的代码可以封装到一个代码块中,在需要使用的时候调用一下函数即可。

Python中的函数很灵活,可以在模块中、类之外定义,其作用域是当前模块;也可以在别的函数中定义,即嵌套函数;还可以在类中定义,即方法。

定义函数

注意:Python作为解释性语言,其函数必须先定义后调用,前面的学习中用到了一些函数,如len()、min()、max()等,这些函数是由Python官方提供的,称为内置函数,不需要我们自己去定义。

自定义函数的语法格式如下:

复制代码
def 函数名(参数列表):
    函数体
    return 返回值

定义函数的关键字为def,函数名需要符合标识符命名规则,函数可以没有参数,也可以有多个参数,多个参数列表之间用逗号进行分隔;如果有返回值,就要在函数体最后用return语句进行返回,如果没有,可以用return None或者省略return 语句。

输入下面代码

复制代码
def calculate_Area(a):
    return a*a
x = int(input("请输入正方形的边长:"))
area = calculate_Area(x)
print("正方形的面积为:{0}".format(area))

代码运行结果(假设输入的边长为3)

复制代码
请输入正方形的边长:3
正方形的面积为:9

代码中没有错误处理机制来捕获并处理用户输入非数字时的情况。

下面代码为改进后的代码

复制代码
def calculate_Area(a):
    return a * a

# 循环直到用户输入有效的边长
while True:
    try:
        x = int(input("请输入正方形的边长:"))
        if x <= 0:
            print("边长必须是正数,请重新输入!")
            continue
        break  # 输入有效,退出循环
    except ValueError:
        print("无效的输入,请输入一个整数!")

area = calculate_Area(x)
print(f"正方形的面积为:{area}")  # 使用 f-string 格式化输出

函数参数

Python中的函数参数使用很灵活,传参可以有多种方式

使用关键字参数调用函数

采用关键字参数调用函数,在函数定义时不需要做额外的工作。在调用时可以不使用关键字参数调用,对于使用关键字参数调用时,参数顺序可以与函数定义时的顺序不同。特别需要注意的是:一旦其中一个参数采用了关键字参数形式传递,则其后所有参数都必须采用关键字参数调用。

示例代码如下

复制代码
def calculate_area(width,height):
    area = width*height
    print("长和宽分别为{0}、{1},面积为{2}".format(width,height,area))
calculate_area(20,20)       #未采用关键字参数函数调用
calculate_area(20,height=20)       #采用关键字参数函数调用
calculate_area(width=20,height=19)
calculate_area(height=20,width=19)
# calculate_area(width=20,20) 该代码若执行,会显示SyntaxError: positional argument follows keyword argument错误

代码运行结果

复制代码
长和宽分别为20、20,面积为400
长和宽分别为20、20,面积为400
长和宽分别为20、19,面积为380
长和宽分别为19、20,面积为380

参数默认值

在定义参数时可以为参数设置一个默认值,调用参数时可以忽略该值。在参数列表中,默认值可以跟在参数类型后面,通过等号提供给参数,在调用时,如果调用者没有传递参数,则使用默认值。

与Java中重载的区别:

在Java语言中采用重载可以实现使用同一个方法调用不同的参数,而Python不支持函数重载,而是使用参数默认值的方式提供类似函数重载的功能。因为参数默认值只需要定义一个函数就够了,而重载需要定义多个函数,这会增加代码量。

示例代码如下

复制代码
def make_drink(name='可乐'):
    print("请给我来一杯{0}".format(name))
make_drink()        #不传入参数时调用默认参数
make_drink('橙汁')   #传入参数时

代码运行结果

复制代码
请给我来一杯可乐
请给我来一杯橙汁

单星号(*)可变参数

函数的参数个数可以变化,可以接受不确定数量的参数,这种参数称为可变参数。可变参数有两种:参数前加单星号(*)和双星号(**)形式。

其中单星号可变参数在函数中被组装成一个元组,如果已经有一个元组变量,在传递的时候需要对元组进行拆包。需要注意的是:若单星号可变参数不是最后一个参数时,后面的参数需要采用关键字参数形式传递。

示例代码如下

复制代码
def calculate_sum(*numbers,multiple=1):
    total = 0
    for number in numbers:
        total += number
    total = total * multiple
    print(total)            #也可以修改代码最后两行为return total * multiple
calculate_sum(20,30,40)
calculate_sum(20,30,40,multiple=3)#若调用multiple参数,必须使用关键字参数
#采用元组或列表作为参数
a = (20,30,40)
calculate_sum(*a)
calculate_sum(30,*a)
# 这里的 a 是一个元组 (20, 30, 40),而 calculate_sum 函数使用的是分散的参数,
# 而不是将整个元组作为一个单独的参数。若尝试将 30(一个整数)和 a(一个元组)作为参数传递给函数时,
# Python 会将它们视为两个独立的参数,但 *numbers 是将这些参数解包为独立的元素。

代码运行结果

复制代码
90
270
90
120

双星号(**)可变参数

双星号可变参数在函数中被组装成一个字典,需要注意的是双星号可变参数必须在正规参数之后,即若此处参数列表改为(**info,sep=':')时,则会发生错误。

示例代码如下

复制代码
def show_info(sep=':',**info):
    print('-----info-----')
    for key, value in info.items():
        print('{0} {1} {2}'.format(key,sep,value))
show_info('->',name='Tony',age = 18 ,gender ='man')#注意键不要加引号
show_info(student_name='Tony',student_no = '1000',sep='-')
dict1 = {'name':'Tony','age':18}
show_info(**dict1,gender='man',sep='=')

代码运行结果

复制代码
-----info-----
name -> Tony
age -> 18
gender -> man
-----info-----
student_name - Tony
student_no - 1000
-----info-----
name = Tony
age = 18
gender = man

函数返回值

主要有三种形式:无返回值、单一返回值和多返回值。

无返回值

示例代码如下

复制代码
def calculate_sum(*numbers,multiple=1):
    if len(numbers) == 0:
        return         #无返回值

上述代码的意义为若未输入数字,则结果为空

单一返回值

针对上述代码改进如下

示例代码如下

复制代码
def calculate_sum(*numbers,multiple=1):
    if len(numbers) == 0:
        return                  #无返回值
    totol = 0
    for number in numbers:
        totol += number
    return totol*multiple       #单一返回值
print(calculate_sum(0))
print(calculate_sum(30,20,10,multiple=2))

代码运行结果

复制代码
0
120

多返回值

有时需要函数返回多个值,简单的方式是使用元组,因为元组作为数据结构可以容纳多个数据,且元组不可变,使用起来比较安全。

示例代码如下

复制代码
def position(time,speed):
    posx = speed[0] * time
    posy = speed[1] * time
    return (posx,posy)#返回X和Y方向的位移
move = position(60.0,(10,-5))
print("物体的位移:({0},{1})".format(move[0],move[1]))

代码运行结果

复制代码
物体的位移:(600.0,-300.0)

函数变量作用域

变量在模块中创建,其作用域是整个模块,称为全局变量。变量也可以在函数中创建,此时默认其作用域为整个函数,称为局部变量。Python提供了一个 global 关键字,可将函数的局部变量作用域修改为全局的。

示例代码如下

复制代码
x = 20          #创建一个全局变量x
y = 20          #创建一个全局变量y

def print_value():
    x = 10      #创建局部变量
    global y    #声明y为全局变量
    y = 10      #修改全局变量的值
    print('函数中 x = {0}'.format(x))
print_value()

print("全局变量 x = {0} y = {1}".format(x,y))

代码运行结果

复制代码
函数中 x = 10
全局变量 x = 20 y = 10

生成器

在一个函数中使用 yield 关键字返回生成器对象,生成器对象是一种可迭代对象,可迭代对象通过_ next _ ()方法获得元素;与return不同的是,return一次返回所有元素,而yield语句只返回一个元素数据,函数调用不会结束,只是暂停,直到_ next _ ()方法被调用,程序继续执行yield后面的语句代码。


需要注意的是:生成器对象特别适合用于遍历一些大序列对象,它无须将对象的所有元素都载入内存后才开始进行操作,仅在迭代至某个元素时才会将该元素载入内存。


示例代码如下

复制代码
def square(num):
    for i in range(1,num+1):
        yield i*i
for i in square(6):    #隐式调用生成器的_ _next_ _ ()方法
    print(i,end=' ')

代码运行结果

复制代码
1 4 9 16 25 36 

嵌套函数

即在函数体中定义函数,嵌套函数的作用域在外部函数体内

示范代码如下

复制代码
def calculate(n1,n2,opr):
    multiple = 3
    #定义相加函数
    def add(a,b):
        return (a+b)*multiple
    #定义相减函数
    def sub(a,b):
        return (a-b)*multiple
    #条件判断
    if opr == '+':
        return add(n1,n2)
    else:
        return sub(n1,n2)
print(calculate(10,20,'+'))
print(calculate(20,10,'-'))

代码执行结果

复制代码
90
30
相关推荐
数据智能老司机11 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机12 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i12 小时前
drf初步梳理
python·django
每日AI新事件12 小时前
python的异步函数
python
这里有鱼汤14 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook1 天前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室1 天前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三1 天前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试