一、函数的基础定义与使用

函数是组织好的、可重复使用的代码块,通过传递的参数返回不同的结果,前面章节已经使用了 Python 定义的函数如range()len()input()等,本章讲解用户自定义的函数。

对于重复使用的代码,可以编写为自定义函数以便于重复使用代码,同时提高开发人员的开发效率。函数可以分为无参函数和带参函数。

用于实现单一或相关联的功能,能大幅提升代码复用性和可读性。

1. 函数的定义语法
def 函数名(参数列表):
    """函数文档字符串(可选,用于说明函数功能)"""
    函数体(要执行的代码)
    return 返回值(可选)
  • def:定义函数的关键字,必须以它开头;
  • 函数名:遵循 Python 命名规范(小写 + 下划线),见名知意;
  • 参数列表:可选,函数接收的输入;
  • 函数文档字符串:用三引号包裹,可通过函数名.__doc__查看;
  • return:可选,用于返回结果,执行到 return 函数会立即结束。
2. 无参函数

以关键字 def 开始,后面跟函数名、小括号、冒号,最后使用 return 退出函数。用表达式可以传递函数的返回值,如果没有返回值,则返回 None

函数名是以字母、数字和下划线组成的字符串,但是不能以数字开头。

示例1

该程序首先定义了无参函数add(),它输出10+20的结果值,return没有返回值,直接使用函数名add()进行调用

示例2

使用函数时经常会犯一些错误,总结如下:

  • 函数的定义要先于函数的调用,否则会出错。
  • 函数体的代码是一个整体,要注意缩进。
  • 定义函数时要使用冒号,但调用时不可以使用冒号。
3.带参函数

Python 带参函数的语法格式如下。

语法:

def 函数名称(形式参数列表):
    代码块
    return [表达式]

通过语法可以看出,带参函数与无参函数的区别是在函数名称后面的小括号中有形式参数列表,简称形参列表。

注意:形式参数列表实际上只是占位符,用于体现参数的个数,每个参数都没有提供具体的数值。

调用带参函数时,需要为每个参数传递对应的实际数值,又称实参列表。

示例 1 是完成加法运算的函数代码。

示例1

当调用函数时,根据传递的实际参数值出现位置与函数定义的形式参数列表进行匹配

示例2

调用带参函数时,传入函数的参数个数必须和声明的参数个数一致当函数包含有多个参数时,一旦实参个数与形参个数不符,就可能出错。为了避免这样的错误发生,Python在函数定义时允许为形式参数指定默认值,从而在调用参数时可以少写参数,省略的参数用默认值为其赋值。

二、函数的参数类型

Python 函数参数有 4 种核心类型,灵活使用能适配不同场景:

参数类型 定义方式 特点 示例
位置参数 def func(a, b): 按参数定义顺序传递,必须传值 func(1, 2)
默认参数 def func(a, b=10): 调用时可省略,使用默认值 func(5) → b=10;func(5, 20) → b=20
关键字参数 调用时指定参数名 无需按顺序传递,提高可读性 func(b=2, a=1)
可变长度参数 *args(元组)/ **kwargs(字典) 接收任意数量的位置 / 关键字参数 def func(*args): print(args)
示例:不同参数类型的使用
# 默认参数
def calculate_area(width, height=1):
    """计算矩形面积,高度默认1"""
    return width * height

print(calculate_area(5))      # 输出:5(height用默认值1)
print(calculate_area(5, 3))   # 输出:15(覆盖默认值)

# 可变参数
def print_info(*args, **kwargs):
    """接收任意位置参数和关键字参数"""
    print("位置参数:", args)    # args是元组
    print("关键字参数:", kwargs)  # kwargs是字典

print_info(1, 2, name="小明", age=18)
# 输出:
# 位置参数: (1, 2)
# 关键字参数: {'name': '小明', 'age': 18}

三、函数的返回值

  • return可以返回任意类型(数字、字符串、列表、字典、甚至另一个函数);
  • returnreturn后无内容,函数默认返回None
  • 可返回多个值,本质是返回元组(可解包)。
# 返回多个值
def get_user_info():
    name = "小红"
    age = 20
    gender = "女"
    return name, age, gender  # 等价于返回 (name, age, gender)

# 解包接收返回值
name, age, gender = get_user_info()
print(name, age, gender)  # 输出:小红 20 女
函数中变量的作用域

作用域是指变量在程序中的应用范围,而变量声明的位置决定它的作用域。Python 按作用域区分有局部变量全局变量

  • 全局变量:指在一个模块中最高级别的变量,有全局作用域,除非被删除,否则存活到程序运行结束,所有函数都能访问全局变量。
  • 局部变量:指定义在函数内的变量,有局部作用域,依赖于定义变量的函数现阶段是否处于活动状态。调用函数时,局部变量产生,暂时存在;一旦函数执行完,局部变量将会被释放。

局部变量和全局变量的使用规则

  • 局部变量的作用域仅限于定义它的函数。
  • 全局变量的作用域在整个模块内部都是可见的。
  • 在同一个函数中,不允许有同名局部变量。
  • 在不同的函数中,可以有同名局部变量。
  • 在同一个程序中,全局变量和局部变量同名时,局部变量具有更高的优先级。

示例

尽量不使用全局变量,非常容易出现数据被意外修改的错误,这种错误很难被发现

内建函数:

函数名 基本语法 核心功能说明 实用示例 示例输出 / 结果
abs() abs(x) 返回数字 x 的绝对值(x 可以是整数、浮点数,或实现了__abs__的自定义对象) abs(-10)``abs(3.14) 10``3.14
bool() bool(x) 将 x 转换为布尔值:0 / 空对象(''、[]、{} 等)返回 False,非空 / 非 0 返回 True bool(0)``bool("hello")``bool([]) False``True``False
float() float(x=0.0) 将 x 转换为浮点数(x 可以是数字、合法数字字符串,无参数返回 0.0) float(5)``float("3.14") 5.0``3.14
int() int(x=0, base=10) 将 x 转换为整数:浮点数直接截断小数部分;字符串需指定进制(默认 10 进制) int(3.9)``int("1010", 2) 3``10
range() range(stop)``range(start, stop[, step]) 生成整数序列(左闭右开),返回 range 对象(可迭代);step 为步长,默认 1 range(5)``range(1, 10, 2) 0-4的序列``1,3,5,7,9
sum() sum(iterable, start=0) 计算可迭代对象(需为数值类型)的总和,start 为初始值(默认 0) sum([1,2,3])``sum(range(5), 10) 6``20
max() max(iterable, *[, key, default])``max(a, b, c, ...) 返回可迭代对象 / 多个参数中的最大值;key 指定排序规则,default 为无元素时返回值 max([3,1,2])``max("apple", "banana", key=len) 3``banana
min() min(iterable, *[, key, default])``min(a, b, c, ...) 返回可迭代对象 / 多个参数中的最小值;参数规则同 max () min([3,1,2])``min(10, 5, 8) 1``5

四、函数的高级特性

1. 匿名函数(lambda)

简化简单功能的函数定义,语法:lambda 参数: 表达式(表达式结果即返回值)。

# 用lambda定义简单的加法函数
add_lambda = lambda a, b: a + b
print(add_lambda(4, 6))  # 输出:10

# 结合列表sort使用(按元素第二个值排序)
nums = [(1, 3), (4, 1), (2, 2)]
nums.sort(key=lambda x: x[1])
print(nums)  # 输出:[(4, 1), (2, 2), (1, 3)]
2. 函数嵌套(闭包)

函数内部定义另一个函数,内部函数可访问外部函数的变量(闭包)。

def outer_func(x):
    def inner_func(y):
        return x + y
    return inner_func  # 返回内部函数

# 调用外部函数,得到内部函数
add_5 = outer_func(5)
# 调用内部函数
print(add_5(3))  # 输出:8(x=5,y=3)
3. 递归函数

函数调用自身,需满足两个条件:

  • 有明确的终止条件(避免无限递归);
  • 每次调用向终止条件靠近。
# 递归计算阶乘(n! = n * (n-1)!)
def factorial(n):
    if n == 1:  # 终止条件
        return 1
    return n * factorial(n-1)  # 递归调用

print(factorial(5))  # 输出:120(5*4*3*2*1)

五、函数的作用域

Python 中变量的作用域分两种:

  • 局部作用域:函数内部定义的变量,仅在函数内有效;
  • 全局作用域:函数外部定义的变量,整个程序可访问(函数内修改需加global关键字)。
# 全局变量
num = 10

def change_num():
    global num  # 声明使用全局变量num
    num = 20    # 修改全局变量
    local_num = 5  # 局部变量
    print("函数内num:", num)  # 输出:20

change_num()
print("函数外num:", num)  # 输出:20
# print(local_num)  # 报错:局部变量无法在外部访问

六.模块与包

1:模块

模块是 Python 中一个重要的概念,实际上就是包含 Python 函数或者类的程序。模块就是一个包含 Python 定义和语句的文件,把一组相关的函数或代码组织到一个文件中,一个文件即是一个模块。模块的文件名 = 模块名 + 后缀.py。模块之间代码共享,可以相互调用,实现代码重用,并且模块中函数名称必须唯一。

(1)模块定义

下面代码演示模块的定义,保存的文件名是 myModule.py

#fileName : myModule.py
def add(a,b):
    print(a+b)

def mul(a,b):
    print(a*b)

在模块 myModule 中,定义了 2 个函数,一个加法函数和一个乘法函数。它们处理的问题是同类的,作为一个模块定义。

(2)模块导入

使用模块中的函数时,要先导入模块才能使用,导入有 2 种方式。

方式一:在一行导入一个模块

import 模块名

方式二:在一行导入多个模块

import 模块名1[, 模块名2[, 模块名3]...]

补充说明

  • 作用域:模块和变量一样也有作用域的区别。如果在模块的顶层导入,则作用域是全局的;如果在函数中导入,则作用域是局部的,其作用域只是所在的函数中。
  • 加载机制:一个模块只能被加载一次,无论它被导入多少次,可以阻止多重导入时代码被多次执行。在实际编码时,推荐直接在顶层导入。
  • 模块分类:导入的模块也分几种,有 Python 的标准库模块、第三方模块和应用程序自定义的模块。
  • 执行逻辑:加载执行时在搜索路径中找到指定的模块,如果是第一次导入,模块将被加载并执行,之后再调用时就不需要再次加载了。

示例1:导入标准库模块sys

包含了Python环境相关的函数

示例2

总结

  1. Python 函数通过def定义,核心要素包括:函数名、参数、函数体、返回值,调用时需匹配参数规则;
  2. 参数类型分位置参数、默认参数、关键字参数、可变参数(*args/**kwargs),适配不同传参场景;
  3. 高级特性包括 lambda 匿名函数、嵌套闭包、递归函数,需注意作用域和递归终止条件,提升代码灵活性。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐