惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
D
Docker
V
Vulnerabilities – Threatpost
T
Tor Project blog
A
Arctic Wolf
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Last Watchdog
The Last Watchdog
PCI Perspectives
PCI Perspectives
J
Java Code Geeks
罗磊的独立博客
S
Security @ Cisco Blogs
L
LangChain Blog
博客园 - 叶小钗
E
Exploit-DB.com RSS Feed
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
I
Intezer
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Vercel News
Vercel News
Know Your Adversary
Know Your Adversary
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
L
Lohrmann on Cybersecurity
D
DataBreaches.Net
Latest news
Latest news
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
T
Threatpost
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
Help Net Security
Help Net Security
Last Week in AI
Last Week in AI
T
Tenable Blog
小众软件
小众软件
T
Troy Hunt's Blog
MongoDB | Blog
MongoDB | Blog
Simon Willison's Weblog
Simon Willison's Weblog
TaoSecurity Blog
TaoSecurity Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
云风的 BLOG
云风的 BLOG
Cloudbric
Cloudbric
Google DeepMind News
Google DeepMind News
S
Securelist
GbyAI
GbyAI
The Hacker News
The Hacker News
W
WeLiveSecurity

博客园 - 箫笛

Python 编程 - 数据类型和数据结构 Python 编程 - 语句 windows - WSL 的安装与使用 shell编程 - dialog 程序使用指南 FE Team - 如何做好前端代码审查 git 提交的撤销和恢复 React15 - redux-saga 如何在saga中实现轮询接口调用? React15 - React CSS Modules BEM命名实践 React15 - React 15 中 componentWillReceiveProps 为什么会多次调用, 同时componentDidUpdate 也会多次调用? React15 - React15类组件多次执行render方法的原因? React15 - React15应用中代码逻辑复用方案 React15 - React状态同步问题解决 React15 - React 15 中 React.pureComponent 的使用场景 React15 - React 15应用在页面渲染时会多次执行类组件的render 函数的原因 React15 - React 15 中能用 componetDidUpdate 代替 componentWillReceiveProps 吗? React15 - React 15 生命周期函数详解 React15 - 如何在React 15中实现自定义的事件订阅与发送(例如组件间通信) React15 - React15应用中的事件订阅和发送机制 React15 - CSS中的BEM规范 React15 - React CSS Modules BEM命名实践 React15 - 写sass 样式文件,嵌套的结构好,还是扁平的结构好? React15 - sass 中 @mixin 和 @extend 的区别是什么? React15 - React 15 应用 如何使用Css moudules 方式进行模块化开发 React15 - React15应用Sass使用指南 React15 - React 15 应用如何进行性能优化?
Python 编程 - 函数
箫笛 · 2026-06-15 · via 博客园 - 箫笛

在 Python 开发中,函数是组织和复用代码的核心结构。通过 def 关键字定义函数,可以接收输入参数、执行特定逻辑并返回结果。下面详细介绍函数定义的各种语法和用法。

1. 基本语法

def 函数名(参数列表):
    """可选的文档字符串"""
    # 函数体
    return 返回值   # 如果没有 return,默认返回 None

示例

def greet(name):
    """向指定的人打招呼"""
    return f"Hello, {name}!"

print(greet("Alice"))  # 输出: Hello, Alice!

2. 参数类型

Python 函数支持非常灵活的参数传递方式。

2.1 位置参数

调用时按定义顺序传入。

def power(base, exponent):
    return base ** exponent

print(power(2, 3))  # 8

2.2 默认参数

为参数提供默认值,调用时可省略。注意:默认参数必须是不可变对象(如 None、数字、字符串),避免使用列表、字典等可变对象(否则会跨调用累积状态)。

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Bob"))           # Hello, Bob!
print(greet("Bob", "Hi"))     # Hi, Bob!

2.3 关键字参数

调用时显式指定参数名,顺序可任意。

print(greet(greeting="Good morning", name="Charlie"))

2.4 可变位置参数 *args

接收任意多个位置参数,在函数内部以元组形式存在。

def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3, 4))   # 10

2.5 可变关键字参数 **kwargs

接收任意多个关键字参数,在函数内部以字典形式存在。

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=30, city="New York")

2.6 参数解包

调用函数时,可用 *** 将序列/字典解包为独立参数。

nums = [2, 3]
print(power(*nums))          # 2**3 = 8

params = {"base": 5, "exponent": 2}
print(power(**params))       # 5**2 = 25

2.7 参数定义顺序(从最不特殊到最特殊)

def func(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
    pass
  • / 前的参数为仅位置参数(不能通过关键字传入)。
  • /* 之间的参数可位置也可关键字。
  • * 后的参数为仅关键字参数(必须通过关键字传入)。
def func(a, b, /, c, *, d):
    print(a, b, c, d)

func(1, 2, 3, d=4)   # 正确
# func(1, 2, c=3, d=4) 也正确
# func(1, 2, 3, 4)      # 错误:d 仅关键字
# func(a=1, b=2, c=3, d=4) # 错误:a,b 仅位置

3. 返回值

  • 使用 return 返回一个值;不写 return 或只写 return 则返回 None
  • 可返回多个值(实际是一个元组)。
def swap(a, b):
    return b, a

x, y = swap(1, 2)   # x=2, y=1

4. 文档字符串(Docstring)

紧贴函数体第一行的多行字符串,用于解释函数用途、参数和返回值。可通过 help(函数名)函数名.__doc__ 查看。

def add(a, b):
    """计算两个数的和。

    参数:
        a (int/float): 第一个数
        b (int/float): 第二个数

    返回:
        int/float: 两数之和
    """
    return a + b

print(add.__doc__)

5. 变量作用域

  • 函数内部赋值的变量默认为局部变量,只在函数内可见。
  • 使用 global 声明全局变量(尽量避免使用)。
  • 使用 nonlocal 声明外层(非全局)函数的变量。
x = 10          # 全局变量
def outer():
    y = 20      # 外层变量
    def inner():
        nonlocal y
        y = 30
        global x
        x = 100
    inner()
    print(y)    # 30
outer()
print(x)        # 100

6. Lambda 表达式(匿名函数)

用于简单单行函数,自动返回表达式结果。语法:lambda 参数: 表达式

square = lambda x: x ** 2
print(square(5))   # 25

# 常用在排序、过滤等
points = [(1, 2), (3, 1), (5, -1)]
points.sort(key=lambda p: p[1])   # 按第二个元素排序
print(points)   # [(5, -1), (3, 1), (1, 2)]

7. 函数是一等对象

可以赋值给变量、作为参数传递、作为返回值返回。

def apply(func, value):
    return func(value)

def double(x):
    return x * 2

result = apply(double, 5)   # 10

8. 类型注解(Type Hints)

Python 3.5+ 支持可选的类型标注,提高代码可读性和 IDE 支持,运行时不会检查类型。

def divide(a: float, b: float) -> float:
    """返回 a / b"""
    return a / b

9. 最佳实践

  • 命名:小写字母加下划线(snake_case),动词或动词短语(get_user, calculate_total)。
  • 单一职责:一个函数只做一件事。
  • 不要滥用可变默认参数def func(items=[]) 是错误的,应使用 def func(items=None) 并在内部初始化为 []
  • 显式优于隐式:尽量使用明确的参数传递,少用 *args**kwargs 除非必要。
  • 加上文档字符串:复杂函数必须写清楚参数和返回值含义。

10. 完整示例

def calculate_average(numbers: list, round_digits: int = 2) -> float:
    """计算列表的平均值,并可选择保留小数位数。

    Args:
        numbers: 数字列表(空列表时返回 0.0)
        round_digits: 四舍五入保留的小数位数,默认 2

    Returns:
        平均值(float)
    """
    if not numbers:
        return 0.0
    avg = sum(numbers) / len(numbers)
    return round(avg, round_digits)

# 调用
print(calculate_average([10, 20, 30]))           # 20.0
print(calculate_average([], round_digits=1))    # 0.0

掌握函数定义是写出清晰、可维护 Python 代码的基础。建议结合 pytest 等工具为函数编写单元测试,确保行为符合预期。