函数

2021-10-09 23:17:23
admin
1410
最后编辑:admin 于 2024-02-14 13:42:30

声明函数

关键字 def 引入一个函数 定义。它必须后跟函数名称和带括号的形式参数列表,后面的冒号勿漏!构成函数体的语句从下一行开始,并且必须缩进

函数必须先定义,后面才能调用。

函数体的第一个语句可以(可选的)是字符串文字。这个字符串文字是函数的文档字符串,描述函数的作用。

def say():                                  #def声明一个函数,勿忘冒号!
    """输出Hello World"""          #文档字符串描述函数的作用。
    print("Hello World!")           #函数体逻辑内容。
say()                                         #程序中调用函数。

变量作用域

函数内部定义的变量称为局部变量,反之函数外部的变量称为全局变量。

局部变量的作用范围只能是函数内部,函数中可以直接访问全局变量,但不能直接给全局变量赋值(须先在函数中 global 下)。如果在函数内部给一个与全局变量同名的变量赋值,则会产生一个新的局部变量。同名的局部变量和全局变量,虽然名字相同,但其实它们是不同的变量,作用域不同,指向不同的对象。

函数的执行会引入一个用于函数局部变量的新符号表。更确切地说,函数中所有的变量赋值都将存储在局部符号表中;而变量引用会首先在局部符号表中查找,然后是外层函数的局部符号表,再然后是全局符号表,最后是内置名称的符号表。因此,全局变量和外层函数的变量不能在函数内部直接赋值(除非是在 global 语句中定义的全局变量,或者是在 nonlocal 语句中定义的外层函数的变量),尽管它们可以被引用。

返回值

函数中的代码执行完后,会返回到调用该函数的代码行,继续执行后续代码。

在函数中,可以使用 return 语句将值返回到调用函数的代码行。

调用有返回值的函数时,需要提供一个变量,以便将返回的值赋给他。

关键字参数与位置参数

实参分为两种:

关键字参数: 在函数调用中前面带有标识符(例如 name=)或者作为包含在前面带有 ** 的字典里的值传入。举例来说,3 和 5 在以下对 complex() 的调用中均属于关键字参数:

complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})

位置参数: 不属于关键字参数的参数。位置参数可出现于参数列表的开头以及/或者作为前面带有 * 的 iterable 里的元素被传入。举例来说,3 和 5 在以下调用中均属于位置参数:

complex(3, 5)
complex(*(3, 5))

可变参数

函数的参数前如果带有一个星号*,则表示它是一个可变参数,适合参数个数不确定的情况。Python 解释器会创建一个元祖赋值给该参数变量,此时函数可以介绍多个参数:

studentInfo = {
    'zhangsan' : 18,
    'lisi'     : 19,
    'wangwu'   : 20,
    'zhaoliu'  : 21,
    }
def printinfo(*students):
    """print the students info"""
    for student in students:
        print(f"学生:{student},年龄:{studentInfo[student]}")
printinfo('lisi', 'zhaoliu')

输出结果:

学生:lisi,年龄:19

学生:zhaoliu,年龄:21

类似的,当函数的参数前如果带有两个星号**,则表示它是一个关键字可变参数。Python 解释器会创建一个字典赋值给该参数变量。

重要警告: 默认值只会执行一次。这条规则在默认值为可变对象(列表、字典以及大多数类实例)时很重要。比如,下面的函数会存储在后续调用中传递给它的参数:

def f(a, L=[]):
    L.append(a)
    return L
print(f(1))
print(f(2))
print(f(3))

这将打印出

[1]
[1, 2]
[1, 2, 3]

如果你不想要在后续调用之间共享默认值,你可以这样写这个函数:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L