Python 函数详解(上)

简介: 本文系统讲解Python函数核心知识:从基本概念、定义调用,到参数类型(位置/默认/关键字/可变长)、返回值机制、变量作用域(全局/局部),再到匿名函数、递归与高阶函数,并配以生活化比喻和实用示例,助你扎实掌握函数编程精髓。(239字)

Python 函数详解

目录

  1. 函数的基本概念
  2. 函数的定义与调用
  3. 函数参数
  4. 返回值
  5. 变量作用域
  6. 匿名函数
  7. 递归函数
  8. 高阶函数
  9. 练习题

1. 函数的基本概念

什么是函数?

函数是一段可重复使用的代码块,用于执行特定任务。它接受输入(参数),进行处理,并返回结果。

就类似于一个加工厂,你给它一些原材料,它帮你进行处理之后返回成品。

生活比喻:

  • 计算器(函数):输入两个数和运算符(原料),内部计算(步骤),输出结果(成品)
  • 洗衣机(函数):输入脏衣服和洗衣液(原料),内部清洗甩干(步骤),输出干净衣服(成品)

为什么使用函数?---解决重复劳动的问题

没有函数的问题:
如果每次计算"两个数的和"都要写 a + b,每次打印"欢迎语"都要写 print("欢迎使用!"),代码会变得冗长、重复,改一处要改很多地方。

函数的好处:

  1. 复用性:一段代码写一次,多次调用,不用重复写
  2. 简洁性:用一个名字代替一堆代码,逻辑更清晰
  3. 可维护性:改功能只需要改函数内部,不用到处改

2. 基础语法、分类、参数与返回值

函数的基本语法

函数是封装可复用逻辑的"工具",用 def 关键字定义,核心是"定义逻辑 → 调用执行"。

1. 函数的定义:"造工具"的步骤

语法格式:

def 函数名(参数列表):
    """函数文档字符串(可选,说明功能)"""
    函数体代码(缩进块)
    return 返回值(可选)
  • def:标记"开始定义函数"的关键字
  • 函数名:自定义名称(见名知意,如 calculate_sum 表示"计算和"),遵循变量命名规则
  • 参数列表:函数的"输入原料",可包含 0 个或多个参数,多参数用逗号分隔
  • 函数体:缩进的代码块,是函数具体执行的逻辑
  • return:"输出结果"的关键字,可返回任意数据;若无 return,函数默认返回 None

2. 函数的调用:"用工具"的过程

定义后,通过 函数名(实际参数) 触发执行。

示例 1:无参数、无返回值

def say_hello():
    """打印欢迎语"""
    print("你好,欢迎学习Python函数!")

say_hello()  # 调用:输出"你好,欢迎学习Python函数!"
say_hello()  # 再次调用,重复执行逻辑

示例 2:有参数、有返回值

def calculate_sum(a, b):
    """计算两个数的和并返回结果"""
    result = a + b
    return result

sum1 = calculate_sum(3, 5)
print("3 + 5 =", sum1)  # 输出:3 + 5 = 8

sum2 = calculate_sum(10, 20)
print("10 + 20 =", sum2)  # 输出:10 + 20 = 30

3. 函数文档字符串(可选但建议写)

用三引号 """ 包裹的字符串,放在函数体开头,用于说明功能、参数、返回值(方便他人理解)。

示例:

def calculate_product(x, y):
    """
    计算两个数的乘积。
    参数:
        x (int/float):第一个乘数。
        y (int/float):第二个乘数。
    返回:
        int/float:两个数的乘积。
    """
    return x * y

# 查看文档(交互式环境用 help(calculate_product))
print(calculate_product.__doc__)

函数的分类

根据参数、返回值、功能,函数可分为以下 4 类:

1. 无参数、无返回值的函数

  • 特点:无需输入"原料",也不输出"成品",仅执行逻辑(如打印、修改全局变量)
  • 示例:
def show_menu():
    print("===== 菜单 =====")
    print("1. 查看个人信息")
    print("2. 修改密码")
    print("3. 退出系统")

2. 无参数、有返回值的函数

  • 特点:无需输入,但会输出结果
  • 示例:
import random

def get_random_num():
    """返回1-100的随机整数"""
    return random.randint(1, 100)

num = get_random_num()
print("随机数:", num)  # 输出:随机数:xxx(1-100之间)

3. 有参数、无返回值的函数

  • 特点:需要输入"原料",但不输出"成品"(常用于直接执行动作)
  • 示例:
def print_info(name, age):
    """打印个人信息"""
    print(f"姓名:{name},年龄:{age}岁")

print_info("张三", 20)  # 输入参数,执行打印,无返回值

4. 有参数、有返回值的函数

def calculate_discount(price, rate):
    """计算打折后价格"""
    final = price * rate
    return final

original = 100
discounted = calculate_discount(original, 0.8)
print(f"原价{original}元,折后{discounted}元")  # 输出:原价100元,折后80.0元

3. 函数的参数

1. 位置参数(必选参数)

  • 特点:调用时,实际参数的顺序、数量必须与定义时完全匹配
  • 示例:
def describe_person(name, age, city):
    print(f"姓名:{name},年龄:{age}岁,城市:{city}")

describe_person("李四", 25, "北京")  # 正确:按位置一一对应
# describe_person("王五", 30)  # 错误:缺少 city 参数

2. 默认值参数

  • 特点:定义时给参数设默认值;调用时,若不传递该参数则用默认值
  • 注意:默认参数必须放在位置参数之后
  • 示例:
def describe_person(name, age, city="上海"):  # city 有默认值
    print(f"姓名:{name},年龄:{age}岁,城市:{city}")

describe_person("李四", 25)  # 用默认值 → 输出:姓名:李四,年龄:25岁,城市:上海
describe_person("王五", 30, "广州")  # 覆盖默认值 → 输出:姓名:王五,年龄:30岁,城市:广州

3. 关键字参数

  • 特点:调用时通过 参数名=值 传递,无需遵循位置顺序,但参数名必须与定义一致
  • 示例:
def describe_person(name, age, city):
    print(f"姓名:{name},年龄:{age}岁,城市:{city}")

# 关键字参数调用,顺序可任意
describe_person(age=25, name="李四", city="北京")  # 正确

4. 可变长参数

用于处理不确定数量的参数:

  • *args:接收任意数量的位置参数,打包成元组
  • **kwargs:接收任意数量的关键字参数,打包成字典

*args 示例:

def calculate_total(*numbers):
    """计算任意多个数的和"""
    total = 0
    for num in numbers:
        total += num
    return total

print(calculate_total(1, 2))  # 输出:3
print(calculate_total(1, 2, 3, 4, 5))  # 输出:15

**kwargs 示例:

def show_info(**info):
    """打印任意多的关键字参数"""
    for key, value in info.items():
        print(f"{key}:{value}")

show_info(name="张三", age=22, major="计算机")
# 输出:
# name:张三
# age:22
# major:计算机

同时使用 args 和 *kwargs:

def func(*args, **kwargs):
    print("位置参数打包:", args)    # 元组形式
    print("关键字参数打包:", kwargs)  # 字典形式

func(1, 2, name="小明", score=90)
# 输出:
# 位置参数打包: (1, 2)
# 关键字参数打包: {'name': '小明', 'score': 90}

参数顺序

注意参数的顺序:
# 参数顺序:位置参数 -> 可变参数 -> 默认值参数 -> 关键字参数
def fn(name, *args, age=19, **kwargs):
    print("位置参数:", name)
    print("可变参数:", args)
    print("默认值参数:", age)
    print("关键字参数:", kwargs)

# fn("tom")
# fn("jerry", "java", gender="男")
fn("jerry", "java", 29, age=30, gender="男")

4. 函数的返回值

return 是函数的"成品出口",用于将内部结果传递到外部。

1. 返回单个值

可返回任意数据类型(int、float、str、列表、字典等)。

示例:

def get_max(num1, num2):
    """返回两个数中的较大值"""
    return num1 if num1 > num2 else num2

max_num = get_max(10, 20)
print("较大的数:", max_num)  # 输出:较大的数:20

2. 返回多个值

Python 中 return 会将多个值打包成元组,调用时可自动解包为多个变量。

示例:

def calculate_stats(numbers):
    """返回列表的总和与平均值"""
    total = sum(numbers)
    average = total / len(numbers)
    return total, average  # 多返回值 → 元组打包

nums = [1, 2, 3, 4, 5]
total, avg = calculate_stats(nums)  # 元组解包
print(f"总和:{total},平均值:{avg}")  # 输出:总和:15,平均值:3.0

3. return 的"终止"作用

函数执行到 return 时会立即终止,后续代码不再执行。

示例:

def check_age(age):
    if age < 0:
        return "年龄不能为负数!"
    print("这句代码在 age<0 时不会执行")  # 被 return 终止

print(check_age(-5))  # 输出:年龄不能为负数!
print(check_age(20))  # 输出:这句代码在 age<0 时不会执行 → None

4. 无 return 时的默认返回值

若函数无 return 或 return 后无值,默认返回 None(表示"无结果")。

示例:

def say_hi():
    print("Hi!")

result = say_hi()
print(result)  # 输出:Hi! → None(先打印 Hi!,再打印返回的 None)

5. 全局变量和局部变量

在 Python 中,变量的"作用范围"(即哪里能访问到这个变量)是区分全局变量和局部变量的核心。简单说:全局变量是"大家都能用"的变量,局部变量是"只有特定小范围能用"的变量

全局变量

定义:在函数外部定义的变量,就是全局变量。它的作用域(能被访问的范围)是整个程序(包括所有函数内部,只要没被局部变量覆盖)。

# 在函数外部定义全局变量
global_num = 100  # 全局变量:整个程序都能访问

def print_global():
    # 函数内部可以直接访问全局变量
    print("函数内访问全局变量:", global_num)

def use_global():
    # 函数内部可以使用全局变量进行计算
    result = global_num * 2
    print("用全局变量计算的结果:", result)

# 调用函数
print_global()  # 输出:函数内访问全局变量:100
use_global()    # 输出:用全局变量计算的结果:200

# 函数外部也能直接访问
print("函数外访问全局变量:", global_num)  # 输出:函数外访问全局变量:100

局部变量

定义:在函数内部定义的变量,就是局部变量。它的作用域仅限当前函数内部,函数外部或其他函数都无法访问。

def create_local():
    # 在函数内部定义局部变量
    local_str = "我是局部变量"  # 局部变量:仅在create_local()内可用
    print("函数内访问局部变量:", local_str)

create_local()  # 输出:函数内访问局部变量:我是局部变量

# 尝试在函数外部访问局部变量 → 报错!
# print("函数外访问局部变量:", local_str)  # 报错:NameError: name 'local_str' is not defined

函数的执行过程

当调用一个函数时,系统会在 栈内存 中为该函数单独分配一块临时内存区域。这块区域专门用来存储:

  • 函数的参数
  • 函数内部定义的局部变量
  • 函数执行的中间状态

此时,局部变量就"存放在这块临时区域里",只能在函数内部被访问(相当于"临时房间里的物品,只有房间内的操作能触及")

函数执行完:"出栈",局部变量的"临时房间"被销毁

当函数执行完毕(比如遇到 return 或函数体结束),栈会执行 "出栈"操作——回收并销毁该函数的临时内存区域。

这意味着:存储局部变量的内存空间被系统释放,局部变量彻底"消失"了。

通俗理解:

  • 调用函数 → 租一个临时仓库(栈中分配临时内存),把局部变量当"货物"存在仓库里
  • 函数执行完 → 退租仓库(栈回收内存),仓库被销毁,里面的"货物"(局部变量)也跟着消失,外部自然找不到

特殊情况:同名变量与 global 关键字

全局变量与局部变量同名

num = 100  # 全局变量

def test_same_name():
    num = 200  # 局部变量(和全局变量同名)
    print("函数内的num(局部):", num)  # 优先用局部变量 → 200

test_same_name()
print("函数外的num(全局):", num)  # 全局变量没变 → 100

global 关键字

默认情况下,函数内只能"访问"全局变量,不能直接"修改"它(如果直接赋值,会被当成定义局部变量)。如果要修改全局变量,必须在函数内用 global 关键字声明。

count = 0  # 全局变量

def correct_modify():
    global count  # 声明:我要修改的是全局变量count
    count = 1     # 现在才是真正修改全局变量
    print("函数内的count(全局):", count)  # 输出:1

correct_modify()
print("函数外的count(全局):", count)  # 全局变量已被修改 → 1

相关文章
|
6天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
2626 22
|
6天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
1151 4
|
云安全 安全 网络安全
|
5天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
|
6天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
|
19天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
3306 52
|
12天前
|
JavaScript 安全 前端开发
Nodejs Brotli decoder 代码执行漏洞 (CVE-2026-111497)10629
Node.js发布安全更新修复Brotli解码器高危RCE漏洞(CVE-2026-111497),建议受影响版本用户立即升级。
2141 2
|
11天前
|
人工智能 JSON Linux
【保姆级】ComfyUI部署教程(下载+安装+配置+工作流,2026最新)
ComfyUI 是一款开源节点式AI生成工具,支持图像、视频、音频及3D内容创作。通过拖拽连线组合模型加载、提示词、采样等节点,构建可复用、易修改的工作流,兼容SD1.5、SDXL、Flux、Qwen Image等主流模型。

热门文章

最新文章