在本教程中,您将通过 Python 中的示例全面掌握函数;什么是函数、函数在程序中的重要性、不同类型的函数、如何定义和调用函数、不同类型的参数等。此外,您还将从初学者到专家的水平,涵盖 Python 中变量作用域和递归的概念。
函数本质上是一个独立的代码块,用于执行特定任务或一组相关任务。函数主要分为两种类型。它们是:
在之前的教程中,您已经看到了许多内置函数的例子,例如 len()、max() 等。内置函数是 Python 内置的函数,最终用户可以访问它来执行他们想要的特定任务。另一方面,用户自定义函数是由用户定义的函数,用于执行特定任务。
接下来,您将学习创建和执行自己的函数。在此之前,让我们讨论一下在 Python 程序中使用函数的好处。
由于以下合理的原因,函数在所有编程语言中都扮演着至关重要的角色。
def < function_name >(< parameter(s) >):
“ “ “ Doc_String ” ” ”
< function _body >
return(< expression >)
上述函数定义的组成部分列表如下。
| 组成部分 | 描述 |
|---|---|
| def | 关键字 def 定义函数头的开始 |
| < 函数名 > | 应为有效的标识符(参考标识符规则)。 |
| < 参数 > | 用于向函数传递值。可选。 |
| : | 表示函数头的结束 |
| “ “ “ 文档字符串 ” ” ” | 用于提供函数文档。可选。 |
| < 函数体 > | 遵循相同缩进级别的有效 Python 语句 |
| return | 返回函数的值。可选。 |
def area_calc():
"""this function gives the area of different shapes"""
pi =3.14
r = 10
print('Area is :',a)
在上面的示例中,我们定义了一个打印圆面积的函数。在进行函数调用之前,它不会执行。函数定义在解释器找到函数调用之前一直处于非活动状态。
函数调用是 Python 函数的另一个重要组成部分。一旦函数创建完成,我们需要通过从另一个函数、程序或 Python 提示符中调用它来执行该函数。要调用函数,请使用以下语法
< function_name >(< argument(s) >)
在这里,在函数调用中,参数指的是传递给函数的值。函数调用中的参数与函数定义中的参数是同义的。我们可以将参数部分留空,但在函数调用和函数定义中都必须有括号。
# this is the function definition
def area_calc(r):
"""this function gives the area of circle"""
pi = 3.14
a = pi*r*r
print('Area is :',a)
#This illustrates function call
area_calc(10)
area_calc(20)
输出
Area is : 314.0 Area is : 1256.0
在这个例子中,area_calc(10) 和 area_calc (20) 是带有参数 10 和 20 的函数调用。
到目前为止,在本教程中,我们详细讨论了 Python 函数中使用的所有组件。现在让我们学习函数的整体工作原理和执行顺序。

程序中的函数只有在被调用时才会激活。函数调用将控制权传递给函数,函数通过执行函数体来执行特定任务。当遇到 return 语句时,最终结果将返回给函数调用,否则它会在函数中输出结果并立即终止函数。
注意:参数在 Python 中通常表示为 arg 或 args。
函数的另一个重要组成部分是参数。参数在函数名之后、括号内定义。参数应使用逗号分隔,参数的数量不受任何限制。
在前面的示例中,area_calc(10) 和 area_calc(20) 介绍了在函数调用中使用单个参数。这些参数在每次函数调用时传递给函数定义中的参数 'r',并接受值 10 和 20 来完成任务。
参数大致分为 4 种类型。
必需参数,也称为位置参数,是在 Python 中向函数传递参数的最简单方法。由于函数调用中的参数与函数定义中的参数相对应,因此应仔细考虑传递参数的数量和位置(顺序)。
#this is function definition
def person(name, age, place):
print(' Hi ,Iam',name ,age,'years old lives in ',place)
# this is function call
person('Chris',17,'USA')
输出
Hi,Iam Chris 17 years lives in USA
在上面的示例中,函数调用 person('Chris',17,'USA') 有 3 个参数,函数定义 person(name,age,place) 有 3 个参数。在这里,函数定义中的参数充当变量,用于保存函数调用的值。这些参数在函数局部定义,当函数被调用时,参数会按照它们的位置顺序传递给参数。因此称为位置参数。
下面的可视化图表清晰地展示了这个概念。

注意:传递的参数顺序必须与函数中参数的顺序相对应。
如果你传递的位置参数顺序不对,会发生什么?显然,函数会照常执行,但结果可能不是你期望的。例如,person('USA',17,'Chris') 会产生结果“Hi, Iam USA 17 years old lives in Chris”,这不是预期的结果。
在考虑要传递的参数数量时,与顺序一样,参数的数量应该与函数中的参数数量相匹配。下面的例子解释了为什么这个参数被称为必需参数。
示例:多一个参数
def person(name, age, place):
print(' Hi ,Iam',name ,age,'years old lives in ',place)
person('Chris','Jake',17,'USA',)
输出
person('Chris','Jake',17,'USA',)
TypeError: person() takes 3 positional arguments
but 4 were given
示例:缺少一个参数
def person(name, age, place):
print(' Hi ,Iam',name ,age,'years old lives in ',place)
person('Chris',17)
输出
person('Chris',17)
TypeError: person() missing 1 required positional argument: 'place'
这里的两个例子表明,传递给函数的参数数量必须与函数定义中的参数数量相匹配。如果我们增加或减少一个参数,结果将会是错误。
简而言之,当一个函数被调用时,Python 中的必需参数或位置参数必须指定要传递的适当数量的参数,并且顺序必须与函数定义中的参数顺序完全相同。
注意:传递的参数数量必须与函数中的参数数量相匹配。
引入 Python 中的关键字参数是为了放宽对必需参数的一些限制。关键字参数的形式为
#this is function definition
def person(name, age, place):
print(' Hi ,Iam',name ,age,'years old lives in ',place)
# this is function call
person(name='Chris',age=17,place ='USA')
person(age=17,place ='USA',name='Chris')
输出
Hi ,Iam Chris 17 years old lives in USA Hi ,Iam Chris 17 years old lives in USA
在上面的示例中,您会注意到高亮显示的函数调用中的参数顺序是乱的。但它仍然输出了正确的答案。这表明当在函数调用中指定关键字参数时,顺序无关紧要,这意味着调用函数通过名称识别分配给参数的相应参数。
示例:关键字引用未声明的参数
def person(name, age, place):
print(' Hi ,Iam',name ,age,'years old lives in ',place)
person(name='Chris',age=17,country ='USA')
输出
person(name='Chris',age=17,country ='USA') TypeError: person() got an unexpected keyword argument 'country'
该示例显示了当关键字引用函数中未声明的参数时会发生什么。它会产生一个异常。因此,为参数和关键字使用相同的名称至关重要。
关键字参数只在要传递的参数顺序上提供了便利,但在要传递的参数数量上没有。当函数调用中的参数数量与参数数量不匹配时,会产生异常,就像位置参数一样。
默认参数,顾名思义,为函数参数提供一个默认值,以应对函数调用期间缺少参数值的情况。默认参数在函数定义中定义,其中参数的形式为
#this is function definition
def person(name='Tom', age=20, place ='UK'):
print(' Hi ,Iam',name ,age,'years old lives in ',place)
# this is function call
person('Chris',17,'USA')
person('Chris')
输出
Hi ,Iam Chris 17 years old lives in USA Hi ,Iam Chris 20 years old lives in UK
在此示例中
由此我们可以推断,默认参数通过允许在函数调用期间省略参数,解除了对参数数量的限制。
在函数调用 person('Chris',17,'USA') 期间,所有参数值都被传递给函数参数,因此它产生结果“ Hi ,Iam Chris 17 years old lives in USA”。
第二次函数调用 person('Chris') 只向函数传递了一个参数值,缺少另外两个参数值。即便如此,它还是通过使用函数中为参数设置的默认值,生成了结果“Hi ,Iam Chris 20 years old lives in UK”。
Python 允许在函数定义中使用可变长度参数(任意参数),以处理我们不太确定函数需要多少参数的情况。根据参数的类型,它分为两种:
任意参数通常通过在参数前放置一个 (*) 星号来定义,例如 *args。*args 也称为非关键字任意参数。
每当参数前缀为星号时,它表示参数的元组打包。函数调用中的参数被打包成一个元组,函数通过其参数名引用该元组。下图是参数元组打包的可视化。tags 是函数定义中的参数,arg1, arg2, arg3, ..., argn 是函数调用期间传递的参数。

def fn(*names):
print(names ,' belongs to',type(names) )
for i in names:
print(i)
fn('Red','Green','Blue')
print('\n')
fn('Bike','Car','Bus','Train')
输出
('Red', 'Green', 'Blue') belongs to
Red
Green
Blue
('Bike', 'Car', 'Bus', 'Train') belongs to
Bike
Car
Bus
Train
在上述示例中
现在我们已经了解了 *args 是什么以及它的用途,让我们来看看 python 函数中的 **kwargs 是什么以及它的用途。
**kwargs 用于向函数传递关键字参数。**kwargs 的工作方式与 *args 相同,但它接受的是关键字参数而不是位置参数。函数通过在参数前加上双星号(**)来表示使用关键字任意参数。**星号表示以键值对形式对参数进行字典打包。
下面给出了一个展示 **kwargs 工作原理的例子
# **Kwargs example
def fn(**names):
print(names ,' belongs to',type(names) )
for key, value in names.items():
print("{} = {}".format(key,value))
fn(Colour_1='Red',Colour_2= 'Green', Colour_3 ='Blue')
fn(Vehicle_1= 'Bike',Vehicle_2 ='Car',Vehicle_3='Bus',Vehicle_4 ='Train')
输出
{'Colour_1': 'Red', 'Colour_2': 'Green', 'Colour_3': 'Blue'} belongs to
Colour_1 = Red
Colour_2 = Green
Colour_3 = Blue
{'Vehicle_1': 'Bike', 'Vehicle_2': 'Car', 'Vehicle_3': 'Bus', 'Vehicle_4': 'Train'} belongs to
Vehicle_1 = Bike
Vehicle_2 = Car
Vehicle_3 = Bus
Vehicle_4 = Train
在这个例子中,我们向名为 fn(**names) 的函数调用了两个任意长度的函数,其中 **names 是关键字参数。** names 接受键值对形式的关键字,即作为字典。函数内部的 'for loop' 检索每个项目并产生结果。
return 语句的语法是
return (< [removed]s) >)
Python 函数中的 return 语句是一个可选语句,它有两个明确的目的
函数在两种情况下会传递一个 None 对象
以下示例说明了在函数中使用 return 语句
def area_calc(x,y):
return(x*y)
a = area_calc(10,15)
print('Area is :',a)
输出
Area is : 150
Python 中的匿名函数是没有名称的函数。匿名函数使用 Lambda 关键字定义。因此,匿名函数在 Python 中也称为 Lambda 函数。
匿名函数的语法是
lambda arg(s) : expression
匿名函数可以接受任意数量的参数,但必须只有一个表达式。它们不能接受多个表达式和命令。Lambda 函数在需要函数对象的地方非常有用。
例如,让我们将前面的示例更改为 lambda 函数的形式;
area_calc =lambda x ,y : x*y
print('Area is ',area_calc(10,20))
输出
Area is 200
在此示例中:
表达式被求值,其值作为函数对象返回,并赋给标识符 area_calc。现在,匿名函数变成了一个普通函数。
变量的作用域是学习编程语言时需要解决的最重要的话题之一。变量的作用域指定了变量在函数、类或程序中的访问权限。根据变量的作用域和生命周期,Python 将变量分为两种类型
以下示例说明了函数中变量的作用域
a = 0 # a is the global variable
def area_calc(x,y): # x and y are local variables
a=x*y
print('Area is ',a) # inside function
area_calc(10,20)
print('Area is ',a) #outside function
print (x*y) #outputs error as x and y are declared inside function
输出
Area is 200 Area is 0 print (x*y) NameError: name 'x' is not defined
递归是函数调用自身的过程。如果一个函数调用自身,那么这个函数就被称为递归函数,这样的调用被称为递归调用。更具体地说,一个函数会重复调用自己,直到达到基本情况。递归的常见结构有两个组成部分:
以下程序演示了在 Python 中使用递归来求一个数的阶乘。在看程序之前,让我们回顾一下如何求 5 的阶乘。
| 求阶乘的通用方法 | 示例:5! |
|---|---|
| n! = n x (n-1)! | 5! = 5 x 4! |
| n! = n x (n-1) x (n-2)! | 5! = 5 x 4 x 3! |
| n! = n x (n-1) x (n-2) x (n-3)! | 5! = 5 x 4 x 3 x 2! |
| 5! = 5 x 4 x 3 x 2 x 1! | |
| n! = n x (n-1) x (n-2) x (n-3) ….3! | 5! = 5 x 4 x 3 x 2 x 1 => 120 |
| n! = n x (n-1) x (n-2) x (n-3) ….3 x 2! | |
| n! = n x (n-1) x (n-2) x (n-3) ….3 x 2 x 1! |
求阶乘的通用方法
从上表我们了解到,一个大问题被分解成相同问题的较小块,并重复这个过程,直到我们达到一个基本情况。在这个例子中,1! 是基本情况,值为 1。