Python第七章 Python函数

第七章 Python函数

函数:是组织好的,可重复使用的,用来实现特定功能的代码段。

7.1 函数的定义

def func_name([params]):
	func_body # 函数体
    [return 返回值]

其中,参数params和返回值是可以省略的

【注意】函数必须先定义,后调用

下面演示几个例子


1、没有参数和返回值

def say_hi():
    print("hi")

say_hi() # hi

2、有参数、无返回值

def add(x, y):
    print(f"{x}+{y}={x+y}")
add(1, 5) # 1+5=6

3、有参数、有返回值

def add(x, y):
    return x + y


print(add(1, 5))  # 6

7.2 无返回值返回None

如果函数没有返回值,那么默认返回None,下面介绍None类型

【说明】Python中有一个特殊的字面量:None,其类型是:<class 'NoneType'>,None表示:空的、无实际意义的意思。函数返回的None,就表示,这个函数没有返回什么有意义的内容。也就是返回了空的意思。

def no_return():
    print("")

res = no_return()
print(res, type(res)) # None <class 'NoneType'>

当然可以显示声明返回None

def return_None():
    return None


res = return_None()
print(res, type(res))  # None <class 'NoneType'>

有的时候也会None表否定结果

def is_mature(age):
    if age > 18:
        return "SUCCESS"
    else:
        return None


result = is_mature(12)

# 如果result不是True的话,表明是未成年
if not result:
    print("未成年,不可以进入")

【None类型的应用场景】

1、用在if判断上

  • 在if判断中,None等同于False
  • 一般用于在函数中主动返回None,配合if判断做相关处理
def is_mature(age):
    if age > 18:
        return "SUCCESS"
    else:
        return None


result = is_mature(12)

# 如果result不是True的话,表明是未成年
if not result:
    print("未成年,不可以进入")

2、用于声明无内容的变量上

定义变量,但暂时不需要变量有具体值,可以用None来代替

name = None

7.3 函数的说明文档

说明文档:对函数进行说明解释,帮助更好理解函数的功能

语法如下

def func(x, y):
    """
    函数说明
    :param x: 形参x的说明 
    :param y: 形参y的说明
    :return: 返回值的说明
    """
    # 函数体
    return res

【操作】PyCharm中,在函数签名下输入""" """然后回车即可自动生成说明文档


下面是一个例子

def add(x, y):
    """
    这是一个相加的函数
    :param x: 被加数
    :param y: 加数
    :return: x + y的和
    """
    return x + y


print(add(1, 5))  # 6

【经验】多写说明文档,不然到最后都看不清函数是干嘛的了。说明文档的内容应该写在函数体之前


【PyCharm查看函数文档】

在PyCharm编写代码时,可以通过鼠标悬停,查看调用函数的说明文档

image-20230925133721651

7.4 函数的嵌套调用

就是一个函数调用另一个函数

def func_a():
    print("func_a")

def func_b():
    print("func_b")
    # 下面调用了另一个函数
    func_a()

func_b()

7.5 变量作用域:局部 & 全局

变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用)

主要分为两类:局部变量全局变量


1、局部变量

所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效

如下,num是定义在函数体内部的,因此在函数体外无法访问

def test():
    num = 100
    print(num)

test()
print(num) # NameError: name 'num' is not defined.

局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量


2、全局变量

所谓全局变量,指的是在函数体内、外都能生效的变量

思考:如果有一个数据,在函数A和函数B中都要使用,该怎么办?

答:将这个数据存储在一个全局变量里面

# 定义全局变量
num = 100

def testA():
    print(num)

def testB():
    print(num)

testA()  # 100
testB()  # 100

【如何在函数内部修改全局变量】

直接修改是不行的

# 定义全局变量
num = 100

def test():
    # 在函数内部声明的局部变量覆盖了全局变量
    num = 200
    print(num)

test()  # 200
print(num) # 100

需要使用global关键词声明全局变量

# 定义全局变量
num = 100


def test():
    # 声明了num是全局变量
    global num
    num = 200
    print(num)


test()  # 200
print(num)  # 200

案例

主菜单效果 查询余额效果
image-20230925140451136 image-20230925140454565
存款效果 取款效果
image-20230925140458276 image-20230925140501795
balance = 5000000


def print_menu():
    """
    print the menu, input and return the selection
    :return: selection
    """
    print("-------------主菜单-------------")
    print("周杰伦,您好,欢迎来到ATM,请选择操作:")
    print("余额查询\t【输入1】")
    print("存款\t【输入2】")
    print("取款\t【输入3】")
    print("退出\t【输入4】")
    return int(input("请输入您的选择:"))


def query_balance():
    """
    query the balance
    :return: None
    """
    print("-------------查询余额-------------")
    print(f"周杰伦,您好,您的余额剩余:{balance}元")


def save_money(money):
    """
    save money
    :param money: the number of money to save
    :return: None
    """
    print("-------------存款-------------")
    global balance
    balance += money
    print(f"周杰伦,您好,您存储{money}元成功")
    print(f"周杰伦,您好,您的余额剩余:{balance}元")


def get_money(money):
    """
    get the money, if the balance is less than money, fail to get
    :param money: the number of money to get
    :return: None
    """
    print("-------------取款-------------")
    global balance
    if balance > money:
        balance -= money
        print(f"周杰伦,您好,您取款{money}元成功")
        print(f"周杰伦,您好,您的余额剩余:{balance}元")
    else:
        print("余额不足,取款失败")


def operation(selection):
    """
    operate according to the selection
    :param selection: 
    :return: 
    """
    if selection == 1:
        query_balance()
    elif selection == 2:
        save_money(50000)
    elif selection == 3:
        get_money(50000)
    else:
        print("输入失败,请重新选择")


if __name__ == '__main__':
    while True:
        selection = print_menu()
        if selection == 4:
            break
        operation(selection)
    print("退出菜单")

7.6 函数多返回值

python的函数可以返回多个返回值

def return_test():
    return "mary", 18, 170.5


name, age, height = return_test()
print(name, age, height)  # mary 18 170.5

可以同时返回不同类型的返回值


如果只取有限变量接受,会报错

def return_test():
    return "mary", 18, 170.5


var1, var2 = return_test() # 错误:too many values to unpack (expected 2)

7.7 函数的多种传参方式

现有四种传参方式

  1. 位置传参
  2. 关键字传参

7.7.1 位置传参

就是默认的传参方式,每个实参按照位置先后与形参对应

def user_info(name, age, gender):
    print(f"您的名字是{name}, 年龄是{age}, 性别是{gender}")


user_info("mary", 18, "female") # 您的名字是mary, 年龄是18, 性别是female

7.7.2 关键字传参

关键字参数:函数调用时通过“键=值”形式传递参数,就是传参的时候显示指明实参和形参的对应关系

作用: 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求.

def user_info(name, age, gender):
    print(f"您的名字是{name}, 年龄是{age}, 性别是{gender}")


user_info(name="mary", age=18, gender="female")  # 您的名字是mary, 年龄是18, 性别是female

顺序是可以调换的

def user_info(name, age, gender):
    print(f"您的名字是{name}, 年龄是{age}, 性别是{gender}")


user_info(name="mary", gender="female", age=18)  # 您的名字是mary, 年龄是18, 性别是female

并且可以和位置参数一起使用,

如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序

def user_info(name, age, gender):
    print(f"您的名字是{name}, 年龄是{age}, 性别是{gender}")


user_info("mary", gender="female", age=18)
user_info(name="mary", 18, "female")  # 会直接有语法错误

7.7.3 缺省/默认参数

缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用).

作用: 当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值.

函数调用时,如果为缺省参数传值则修改默认参数值, 否则使用这个默认值

def user_info(name, age, gender="male"):
    print(f"您的名字是{name}, 年龄是{age}, 性别是{gender}")


user_info("mary", 18)  # 您的名字是mary, 年龄是18, 性别是male
user_info("mary", 18, "female")  # 您的名字是mary, 年龄是18, 性别是female

7.7.4 可变参数

不定长参数:不定长参数也叫可变参数. 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景.

作用: 当调用函数时不确定参数个数时, 可以使用不定长参数

不定长参数的类型:

  1. 位置传递
  2. 关键字传递

1、位置传递

传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递

def func(*args):
	print(args)

【说明】这个参数名字可以是其他的,没有要求用args即可

def print_names(*names):
    print(names) # ('mary', 'lucy', 'bob')
    print(type(names)) # <class 'tuple'>


print_names("mary", "lucy", "bob")  # mary lucy bob

如果由位置传参的话,未知参数一定在可变参数前面

def print_names(age, *names):
    print(age, names) # 18 ('mary', 'lucy', 'bob')


print_names(18, "mary", "lucy", "bob")  

2、关键字传递

  • 参数是“键=值”形式的形式的情况下, 所有的“键=值”都会被kwargs接受, 同时会根据“键=值”组成字典.
  • 参数前面用**修饰
def user_info(**kwargs):
    print(kwargs)  # {'name': 'tom', 'age': 18, 'height': 170}
    print(type(kwargs))  # <class 'dict'>


user_info(name="tom", age=18, height=170)

7.8 函数作为参数传递

  1. 函数本身是可以作为参数,传入另一个函数中进行使用的。
  2. 将函数传入的作用在于:传入计算逻辑,而非传入数据
def func_arg_test(func):
    func(1, 3)


def compute(a, b):
    print(f"a={a}, b={b}")


func_arg_test(compute)  # a=1, b=3

7.9 lambda匿名函数

函数的定义中

  • def关键字,可以定义带有名称的函数
  • lambda关键字,可以定义匿名函数(无名称)

有名称的函数,可以基于名称重复使用;无名称的匿名函数,只可临时使用一次


匿名函数定义语法:

lambda 参数列表: 函数体(一行代码)
  • lambda 是关键字,表示定义匿名函数
  • 传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数
  • 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
def func_arg_test(compute):
    return compute(1, 3)


result = func_arg_test(lambda x, y: x + y)
print(result)  # 4
posted @ 2023-10-07 11:36  Crispy·Candy  阅读(23)  评论(0编辑  收藏  举报