函数

Python
作者

yangjh

发布日期

May 19, 2022

函数是可重用的代码块,使用函数可以帮助我们组织代码的结构。我们创建函数的目的,是能在程序运行中多次使用一系列代码,而不用重复书写代码。

创建函数

  • Python使用def关键词创建函数,后跟函数名与括号内的参数列表。
  • 函数可以没有参数,也可以有多个参数,多个参数之间用逗号隔开。
  • 函数主体接收参数,实现特定功能。
  • 可以使用pass关键字忽略函数主体部分的编写。
  • 可以通过return语句指定返回值。
def function_name(arg1, arg2, arg3, .... argN):
     #statement inside function
     return 

我们看一个函数的例子,下面的函数将计算指定范围的整数之和:

def sum(start, end):
    result = 0
    for i in range(start, end + 1):
        result += i
    print(result)

sum(1, 10)

在上面的代码中,我们定义了一个叫作sum()的函数,该函数有两个参数(startend),该函数将从start开始,累加到end,最后打印出累积之和。代码运行的结果为55。

文档字符串

  • 文档字符串(Documentation Strings),也叫docstrings
  • DocStrings 本质是位于函数主体开头的多行注释,其目的是让函数更易于理解。
  • 可通过函数的__doc__属性来获取函数的文档字符串。

例如:

def print_max(x, y):
    '''Prints the maximum of two numbers.

    The two values must be integers.'''
    # 如果可能,将其转换至整数类型
    x = int(x)
    y = int(y)

    if x > y:
        print(x, 'is maximum')
    else:
        print(y, 'is maximum')

print_max(3, 5)
print(print_max.__doc__)

输出的结果为:

$ python function_docstring.py
5 is maximum
Prints the maximum of two numbers.

    The two values must be integers.

函数的参数

Python函数中参数的数量可以是任意多个。只要是Python允许的类型,都可以作为参数。

形参与实参

  • 形式参数是未赋值的函数参数。
  • 实际参数是指具有具体值的参数。
  • 实参与形参的区别是变量是否传递具体值。
  • Python 中函数定义时要求形参在前,实参在后。
  • 一旦定义了形参,在调用函数时必须给形参赋值并实参化,否则程序将会报错。

例如,为了在引用函数时更加方便,可以通过赋值语句为参数设定默认值。

def func(i, j = 100):
    print(i, j)

上述定义的函数func()有两个参数iji在函数定义中是形参,j的默认值为100,是实参,这意味着我们在调用这个函数的时候可以忽略掉j的值,比如func(2),运行结果为2 100

全局变量和局域变量

全局变量指的是不属于任何函数,但又可以在函数内外访问的变量。局域变量指的是在函数内部声明的变量,局域变量只能在函数内部使用,无法在函数外访问(函数执行完后,会销毁内部定义的局部变量)。

案例:在函数内部访问全局变量

global_var = 12         # 定义全局变量
def func():
    local_var = 100     # 定义局部变量
    print(global_var)   # 可以在函数内部访问全局变量
func()                  # 调用函数func()
print(local_var)        # 会出现错误,无法访问变量local_var

案例:局域变量覆盖全局变量

xy = 100         # 定义全局变量xy
def func():
    xy = 200    # 定义局部变量xy
    print(xy)   # 此时访问的是局部变量xy
func()          # 调用函数func()
"""
结果为200
这种写法很容易使作者和读者混淆,应尽量避免。
"""

该代码显示的结果是200,不是100。但这种写法很容易使作者和读者混淆,应尽量避免。

案例:在函数内部修改全局变量

  • 使用global关键字,可将局部变量同全局变量绑定在一起。
  • 使用global关键字声明全局变量时,无法直接赋值。比如“global t = 1”的写法存在语法错误。

例如:

t = 1
def increment():
    global t    # 现在的变量t在函数内外都是一致的
    t = t + 1
    print(t)    # 输出 2
increment()
print(t)        # 输出 2

函数的调用

使用函数前,必须先声明与定义函数。

函数的两种使用方式

  • 调用函数时不带括号,表示调用函数本身,当特定事件发生时,才执行函数。
  • 调用函数时带上括号,表示立即执行函数,意味着立即得到函数具体的执行结果。

函数传参

为函数传递参数值的方法有两种:位置参数和关键字参数。

位置参数

def named_args(name, greeting):
named_args('jim', 'Hello')

关键字参数

def named_args(name, greeting):
    print(greeting + " " + name)
named_args(name='jim', greeting='Hello')
named_args(greeting='Hello', name='jim')
named_args('jim', greeting='hello')

上述代码运行结果都是“hello jim“。

关键字参数使用“name=value”的名称、值对传递数据,正如上面代码演示的那样,使用关键字参数的时候,参数的顺序是可以调换的,

位置参数和关键字参数混用

  • 混合使用时只能先使用位置参数,后使用关键字参数。

函数返回值

  • 在函数主体中使用return语句,可以指定返回值。
  • return语句也可以不返回值,而是用来退出函数。
  • 不指定return的返回值,则会返回None值。
  • return语句中使用逗号,可指定多个返回值。

案例1:指定单个返回值

def sumReturn(start, end):
    result = 0
    for i in range(start, end + 1):
        result += i
    return result

a = sumReturn(1, 5)
print(a)

在上面这段代码中,我们定义了有返回值的函数sumReturn(),并将其结果赋值给变量a。上面代码的运行结果为15。

案例2:不指定返回值

return语句也可以不返回值,而是用来退出函数(实际上会返回None,为NoneType对象)。每一个函数都在其末尾隐含了一句return None,除非你写了你自己的 return 语句。

def sum2(start, end):
    if(start > end):
        print("start should be less than end")
        return
    result = 0
    for i in range(start, end + 1):
        result += i
    return result

s = sum2(110, 50)
print(s, type(s))

上述代码的运行结果如下:

start should be less than end
None <class 'NoneType'>

在 Python 中,如果你不指定return的返回值,则会返回None值。

案例3:返回多个值

我们可以通过在return语句中使用逗号,将多个值返回,这种返回值的类型是元组。例如:

def bigger(a, b):
    if a > b:
        return a, b
    else:
        return b, a

s = bigger(12, 100)
print(s)
print(type(s))

运行结果为:

(100, 12)
<class 'tuple'>

回调函数

回调函数是一个在编程中非常有用的概念。它可以被理解为一个“被回电的电话号码”。假设你在一个服务台留下你的电话号码,请求他们在有新消息时给你回电话。在这里,你留下的电话号码就像是一个回调函数。当服务台有新消息时,他们就“调用”(即拨打)你的电话号码(即你的回调函数),并将消息传递给你。

在Python中,回调函数的应用类似于这个例子。它是一个你定义的函数,你将这个函数传递给另一个函数,以便在适当的时候被后者调用。这常用于异步编程,事件处理或在某些操作完成时执行特定的代码。

在Python函数中,回调另外一个函数的方式是使用callback

让我们通过一个简单的Python示例来说明这一点。

假设你有一个下载函数,用于从互联网下载文件。下载可能需要一些时间,而在下载完成后,你希望自动执行某些操作,比如显示一条消息。这里就可以使用回调函数。

def download_file(url, callback):
    # 假设这是下载文件的代码
    # ...
    print(f"正在从 {url} 下载文件...")

    # 假设下载完成了
    download_complete = True

    # 当下载完成时,调用回调函数
    if download_complete:
        callback(url)

def my_callback(url):
    print(f"下载完成: {url}")

# 调用 download_file 函数,并传入 my_callback 作为回调函数
download_file("http://example.com/myfile", my_callback)

在这个例子中,my_callback 函数就是一个回调函数。我们将它作为参数传递给 download_file 函数。当文件下载完成后,download_file 函数调用 my_callback,并传递了URL作为参数。

这种方式使得 download_file 函数更加通用和灵活,因为它可以与任何提供的回调函数一起工作,而不仅仅是固定的操作。

lambda函数

Lambda函数在Python中是一种快速定义单行的小函数的方式。你可以把它想象成一个快餐店里的速食——简单、快速,适合在不需要复杂菜单的场合下使用。

假设你正在组织一个聚会,你有一个名单列表,你想根据每个人的名字的长度来排序这个列表。你可以用一个完整的函数来做这件事,但如果使用lambda函数,就像是用一个快捷方式一样,速度更快,代码更简洁。

用常规函数,代码可能是这样的:

def get_length(name):
    return len(name)

names = ["Alice", "Bob", "Alexander"]
names.sort(key=get_length)

这段代码定义了一个名为get_length的函数,用于获取字符串的长度。然后,它使用这个函数作为排序的依据。

使用lambda函数,可以这样写:

names = ["Alice", "Bob", "Alexander"]
names.sort(key=lambda name: len(name))

这里,lambda name: len(name)是一个简单的匿名函数,它接收一个参数name,返回name的长度。这种方式不需要定义一个完整的函数,使得代码更加紧凑和易读。

Lambda函数是一种编写小型匿名函数的方式。它通常用于需要函数作为参数的情况,如排序、过滤等,而且这个函数相对简单,只需要一行就能完成。

常用内置函数

函数名 功能
id() 查看变量内存地址
type() 查看变量
dir() 列出输出对象的内置方法
print() 打印信息到终端或文件
range() 指定循环的起始值和结束值
enumerate() 同时取出序列的位置索引和对应的值

参考文献

  1. 其他流程控制工具 — Python 3.10.6 文档
回到顶部