深入理解Python函数定义与调用:从基础到实践
函数是指可重用的程序片段。它们允许您为代码块命名,从而允许您在程序中的任何位置以该特殊名称运行该块任意次数。这称为调用函数。

我们使用了许多内置函数,例如 len 和 range。
可以使用 def 关键字定义函数。该关键字后面是函数的标识符名称,后面是一对括号(可能包括一些变量的名称)以及结束该行的冒号。
随后的语句块是该函数的一部分。下面的例子将展示这是多么简单:
def say_hello():
# 该块属于这一函数
print('hello world')
# 函数结束
say_hello() # 调用函数
say_hello() # 再次调用函数
输出:
hello worldhello world
它是如何运作的
我们按照上面解释的方式定义了一个名为 say_hello 的函数。该函数不带参数,因此括号中没有声明变量。函数的参数只是简单地输入到函数中,这样我就可以向它传递不同的值并得到相应的结果。
请注意,我们可以调用同一函数两次,这意味着我们不必再次重写代码。
功能参数
函数中的参数通过将参数放在定义函数的一对括号内来指定,并用逗号分隔。当我们调用函数时,我们以相同的形式提供所需的值。注意这里使用的术语——定义函数时给出的名称称为“参数”,调用函数时提供给函数的值称为“参数”。
def print_max(a, b):
if a > b:
print(a, '是比较大的数')
elif a == b:
print(a, '等于', b)
else:
print(b, '是比较大的数')
# 直接传递字面值
print_max(3, 4)
x = 5
y = 7
输出
4 是比较大的数7 是比较大的数
它是如何运作的
在这里,我们将函数命名为 print_max 并使用两个参数 a 和 b。我们使用一个简单的 if...else 语句来查找较大的数字并将其打印出来。
第一次调用函数 print_max 时,我们直接将该数字作为参数提供给函数。
在第二次调用时,我们以变量作为参数来调用函数。 print_max(x, y) 会使实参 x 的值赋给形参 a,实参 y 的值赋给形参 b。 print_max 在这两个调用中的工作方式相同。
局部变量
当你在函数的定义中声明变量时,它们与函数外部的同名变量没有任何关系,也就是说,这些变量名只存在于函数本地(Local)。
这称为变量的范围。
所有变量的范围是定义它们的块,从定义它们的名称的定义点开始。
案件:
x = 50
def func(x):
print('x 是:', x)
x = 2
print('改变局部变量x为', x)
func(x)
print('x 仍然为', x)
输出:
x 为:50改变局部变量x为 2x 仍然为 50
它是如何运作的
当我们第一次打印出函数块第一行中名为 x 的值时,Python 使用函数声明上方主代码块中声明的该参数的值。
接下来,我们将值 2 赋给 x。 x 是我们函数的局部变量。因此,当我们改变函数中x的值时,主代码块中的x不会受到影响。
通过最后的打印语句,我们显示了主代码块中定义的 x 的值,从而确认它实际上不受先前调用的函数中的局部变量的影响。
全球声明
如果你想给一个位于程序顶部的变量赋值(也就是说,它不存在于任何作用域中,无论是函数还是类),那么你必须告诉Python该变量不是本地的,但全球的。 。
我们需要通过全球声明来做到这一点。因为如果不使用global语句,就不可能给函数外部定义的变量赋值。
您可以使用函数外部定义的变量的值(假设函数中没有同名变量)。然而,这种方法是不鼓励的,应该避免,因为程序的读者很难弄清楚变量的确切定义位置。
通过使用global语句,可以清楚的看出这个变量是在最外层代码块中定义的。
案件:
x = 50
def func():
global x
print('x 为:', x)
x = 2
print('改变全局变量为', x)
func()
print('x的值为', x)
输出:
x 为: 50改变全局变量为 2x的值为 2
它是如何运作的
global语句声明x是一个全局变量——因此,当我们在函数中给x赋值时,这种改变会影响我们在主代码块中使用的x的值。
您可以在同一条全局语句中指定多个全局变量,例如全局x、y、z。
默认参数值
对于某些函数,您可能希望将某些参数设置为可选并使用默认值,以避免用户不想为其提供值的情况。默认参数值可以有效帮助解决这种情况。
您可以通过在函数定义中附加赋值运算符(=)来指定参数的默认参数值。
案件
def say(message, times=1):
print(message * times)
say('Hello')
say('World', 5)
输出
HelloWorldWorldWorldWorldWorld
它是如何运作的
名为 say 的函数按给定次数打印字符串。如果我们不提供数值,则默认情况下该字符串将仅打印一次。我们通过为 times 参数指定默认参数值 1 来实现此目的。
第一次使用 say 时,我们只提供字符串,因此该函数只会打印一次字符串。第二次使用 say 时,我们提供了字符串和参数 5,表示我们要说 (Say) 该字符串五次。
注意
只有参数列表末尾的参数才能被分配默认参数值,这意味着在函数的参数列表中,具有默认参数值的参数不能位于没有默认参数值的参数之前。
这是因为值是根据参数的位置依次赋值的。例如,def func(a, b=5) 有效,但 def func(a=5, b) 无效。
关键字参数
如果你有一些带有很多参数的函数,而你只想指定其中的一部分,那么你可以通过命名的方式给这些参数赋值——这就是关键字参数(Keyword Arguments)——我们使用命名(keyword)而不是位置命名(正如我们到目前为止所做的那样)在函数中指定参数
这有两个主要优点
其一,我们不再需要考虑参数的顺序,使用函数会更容易。
其次,我们可以只为那些我们希望分配的参数赋值,只要所有其他参数都有默认参数值即可。
案件
def func(a, b=5, c=10):
print('a 是:', a, ' b 是:', b, ' c是:', c)
func(3, 7)
func(25, c=24)
func(c=50, a=100)
输出
a 是: 3 b 是: 7 c是:10a 是: 25 b 是: 5 c是:24a 是: 100 b 是: 5 c是:50
它是如何运作的
名为 func 的函数有一个没有默认参数值的参数,后面跟着两个参数,每个参数都有默认参数值。
第一次调用函数 func(3, 7) 时,参数 a 获取值 3,参数 b 获取值 7,c 获取默认参数值 10。
在第二次调用函数 func(25, c=24) 时,变量 a 由于其位置首先获取值 25。然后,由于命名(即关键字参数)规范,变量 c 获取值 24。变量 b 获取默认参数值 5。
在对函数 func(c=50, a=100) 的第三次调用中,我们都使用关键字参数来指定值。这里注意,虽然a是在c之前定义的,但我们仍然在变量a之前指定变量c。
可变参数
有时你可能想定义一个可以有任意数量变量的函数,即参数的数量是可变的。这可以通过使用星号来实现。
案件
def total(a=5, *numbers, **phonebook):
print('a', a)
#遍历元组中的所有项目
for num in numbers:
print('num项为:', num)
#遍历字典中的所有项目
for key, val in phonebook.items():
print(key,val)
print(total(10,1,2,3,Jack=1123,John=2231,Inge=1560))
输出
a 10num项为: 1num项为: 2num项为: 3Jack 1123John 2231Inge 1560None
它是如何运作的
当我们声明一个星号参数(例如*param)时,从这里到最后的所有位置参数都将被收集并组装成一个名为“param”的元组。
同样,当我们声明一个双星号参数如**param时,从这里到最后的所有关键字参数都会被收集并组装成一个名为param的字典。
返回声明
return语句用于从函数返回,即中断函数。我们还可以选择在中断函数时返回一个值
def maximum(x, y):
if x > y:
return x
elif x == y:
return '两个数相等'
else:
return y
print(maximum(2, 3))
输出:
3
它是如何运作的
最大值函数将返回参数中的最大值,在本例中是提供给函数的值。它使用一组简单的 if...else 语句来查找较大的值并返回它。
需要注意的是,如果return语句没有匹配到任何值,则表示返回None。 None 是 Python 中的一种特殊类型,代表虚无。例如,它用于指示变量没有值。如果它有值,则其值为 None。
每个函数末尾都有一个隐式 return None ,除非您编写自己的 return 语句。您可以运行 print(some_function()) 其中 some_function 不使用 return 语句,如下所示:
def some_function():
pass
Python中的pass语句用于表示没有内容的语句块。
暗示:
有一个名为 max 的内置函数已经实现了“求最大数”的功能,因此只要有可能就使用这个内置函数。
DocStrings文档字符串
Python 有一个非常漂亮的功能,叫做文档字符串(Documentation Strings),通常用另一个更短的名字来称呼,docstrings。
DocStrings 是一个重要的工具,您应该使用它来帮助您更好地记录程序并使它们更易于理解。令人惊奇的是,我们甚至可以在程序实际运行时通过函数获取文档!
案件
def print_max(x, y):
'''打印两个数值中的最大数。
这两个数都应该是整数'''
# 如果可能,将其转换至整数类型
x = int(x)
y = int(y)
if x > y:
print(x, '大些')
else:
print(y, '大些')
print_max(3, 5)
print(print_max.__doc__)
输出
5 大些打印两个数值中的最大数。这两个数都应该是整数
它是如何运作的
函数的第一个逻辑行中的字符串是函数的文档字符串 (DocString)。这里需要注意的是,文档字符串也适用于后面相关章节中将提到的模块和类。
该文档字符串约定的是多行字符串,其中第一行以某个大写字母开头,以句点结尾。第二行是一个空行,后面是从第三行开始的详细说明。
强烈建议您在所有重要功能的所有文档字符串中遵循此约定。
我们可以通过函数的 __doc__ (注意双下划线)属性(属于函数名称)来获取函数 print_max 的 docstring 属性。请记住,Python 将所有事物都视为对象,其中包括函数。我们将在稍后的“类”章节中讨论有关对象的更多细节。
自动化工具可以通过这种方式从您的程序中检索文档。因此,我强烈建议您为您编写的所有重要函数提供文档字符串。 Python 发行版附带的 pydoc 命令使用文档字符串的方式与 help() 类似。
嵌套函数
Python 允许创建嵌套函数。换句话说,我们可以在函数内定义函数,而现有的作用域和变量生命周期保持不变。
注意: 1. 外部函数的变量可以被内部函数使用,但不能被内部函数修改。修改需要添加关键字nonlocal
def max(a,b):
return a if a>b else b
print(max(5,2)) #5
def the_max(x,y,z):
c = max(x,y)
return max(c,z)
print(the_max(1,5,3)) #5
输出
55
嵌套函数功能:
1.封装-数据隐藏:外部无法访问“嵌套函数”,
2.减少重复代码
3. 关闭
关闭
什么是闭包?
如果一个函数定义在另一个函数的范围内并引用外部函数的变量,则该函数称为闭包。
闭包是 Python 支持的一项功能,允许在非全局作用域中定义的函数引用其周围空间中的变量。这些周围空间中引用的变量称为该函数的环境变量。
环境变量和这个非全局函数一起形成一个闭包。
def outer():
a = 1
def inner():
print(a)
return inner
inn = outer()
inn() #1
闭合特性:
函数返回的函数对象。当这个函数对象被执行时,它依赖于非函数内部的变量值。此时函数实际返回的内容如下:
1个函数对象
2函数对象需要使用的外部变量和变量值
在函数外部使用内部函数
总结
我们已经研究了函数的许多方面,但我们仍然没有涵盖所有类型的函数。不过,我们已经涵盖了您每天使用的大部分 Python 函数。
接下来,我们将学习如何创建和使用 Python 模块。
01-Python安装教程及特性介绍-新手python基础知识
02-Python你应该知道这些
03python—9个基本常识-python初学者入门系列
05-Python——列表、原语、字典、集合操作全集:推荐合集
06篇,学习python循环和分支
07-Python函数详解
08-python中的包和模块