目录

函数的定义:代码复用的基石

参数类型:灵活传递数据的关键

形参与实参:参数传递的基本概念

默认参数:简化常见调用场景

位置参数:按顺序传递参数

关键字参数:明确参数含义

可变参数:处理不确定数量的参数

元组类型可变参数(*args)

字典类型可变参数(**kwargs)

返回值:函数结果的输出

匿名函数:简洁的一次性函数

变量作用域:变量的可见范围

LEGB 规则详解

global 关键字:修改全局变量

nonlocal 关键字:修改嵌套作用域变量

闭包与装饰器:函数式编程的高级特性

闭包:携带状态的函数

装饰器:增强函数功能的利器

总结


在 Python 编程世界中,函数是构建程序的核心基石。它不仅能让代码结构更清晰、复用性更高,更能通过灵活的参数设计和高级特性实现复杂功能。本文将从函数的基础定义出发,深入解析各类参数类型、匿名函数、变量作用域以及闭包与装饰器等高级特性,帮助你全面掌握 Python 函数的精髓。

函数的定义:代码复用的基石

函数本质上是用函数名存储的可执行代码块,它封装了一系列操作,能接收输入参数并返回处理结果。通过函数,我们可以将复杂问题拆解为多个独立的功能模块,大幅提升代码的可读性和维护性。

函数定义的基本语法如下:

def 函数名(参数列表):

"""函数文档字符串"""

函数体

return 返回值

其中,函数名应遵循标识符命名规则,参数列表用于接收外部传入的数据,函数体是实现具体功能的代码集合,return 语句用于返回函数执行结果。

参数类型:灵活传递数据的关键

Python 函数提供了多种参数类型,灵活运用这些参数能让函数更具通用性和扩展性。

形参与实参:参数传递的基本概念

  • 形参变量:在函数声明时定义的参数,它是一种占位符,用于标识函数需要接收的值,本身没有实际数据。形参的存在提升了函数的灵活性,扩展了函数的功能范围。
  • 实参(实际参数):在函数调用时传入的具体数据,用于给形参赋值。实参可以是常量、变量、表达式或函数调用等。

参数传递的本质是将实参的值赋给形参的过程,例如:

def add(a, b): # a和b是形参

return a + b

result = add(3, 5) # 3和5是实参

默认参数:简化常见调用场景

默认参数是指在函数声明时给形参赋予默认值的参数。当函数调用时如果没有为该参数传递值,则使用默认值;如果传递了值,则使用传递的新值。

默认参数的语法格式如下:

def 函数名(参数1, 参数2=默认值):

函数体

使用默认参数时需要注意,默认参数必须位于非默认参数之后,否则会导致语法错误。

示例代码:

def greet(name, message="Hello"):

return f"{message}, {name}!"

print(greet("Alice")) # 使用默认message:Hello, Alice!

print(greet("Bob", "Good morning")) # 使用传递的message:Good morning, Bob!

位置参数:按顺序传递参数

位置参数是最基础的参数类型,它要求实参与形参按照位置一一对应赋值。在函数调用时,第一个实参赋给第一个形参,第二个实参赋给第二个形参,以此类推。

示例代码:


def describe_person(name, age, city):

return f"{name} is {age} years old and lives in {city}."

print(describe_person("Alice", 30, "New York"))

# 输出:Alice is 30 years old and lives in New York.

如果位置错误,会导致参数赋值错误,从而产生逻辑错误,因此使用位置参数时需特别注意参数顺序。

关键字参数:明确参数含义

关键字参数允许在函数调用时通过指明形参名称来赋值,无需严格按照位置顺序传递。这种方式使函数调用更清晰,尤其适合参数较多的情况。

关键字参数的调用格式如下:


函数名(参数1=值1, 参数2=值2)

需要注意的是,关键字参数必须在位置参数之后赋值

示例代码:


# 使用关键字参数调用上述describe_person函数

print(describe_person(name="Bob", city="London", age=25))

# 输出:Bob is 25 years old and lives in London.

可变参数:处理不确定数量的参数

当函数需要接收的参数数量不确定时,可变参数就能发挥作用。Python 提供了两种可变参数类型:

元组类型可变参数(*args)

*args用于接受多个位置参数,这些参数会被打包成一个元组传递给函数。在函数内部,可以通过遍历元组来处理所有传入的参数。

示例代码:


def sum_numbers(*args):

total = 0

for num in args:

total += num

return total

print(sum_numbers(1, 2, 3)) # 输出:6

print(sum_numbers(10, 20, 30, 40)) # 输出:100

字典类型可变参数(**kwargs)

**kwargs用于接受多个关键字参数,这些参数会被打包成一个字典传递给函数,其中字典的键是参数名,值是对应的参数值。

示例代码:


def print_info(** kwargs):

for key, value in kwargs.items():

print(f"{key}: {value}")

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

# 输出:

# name: Alice

# age: 30

# city: New York

返回值:函数结果的输出

返回值是函数的执行结果,通过return语句实现。在 Python 中,函数默认返回None(如果没有显式的 return 语句)。函数还支持返回多个值,此时这些值会默认使用元组封装后返回。

示例代码:


def calculate(a, b):

sum_ab = a + b

product_ab = a * b

return sum_ab, product_ab # 返回多个值,实际是返回元组

result = calculate(3, 5)

print(result) # 输出:(8, 15)

sum_val, product_val = calculate(3, 5) # 解包元组

print(sum_val, product_val) # 输出:8 15

匿名函数:简洁的一次性函数

匿名函数是指没有函数名的函数,在 Python 中通过lambda关键字定义,其语法格式如下:


lambda 参数列表: 表达式

匿名函数的返回值就是表达式的计算结果,且表达式必须是单行的,不能包含循环、条件语句块等复杂逻辑。

匿名函数通常用于需要临时定义简单函数的场景,例如作为高阶函数的参数。

示例代码:


# 定义一个计算两数之和的匿名函数

add = lambda x, y: x + y

print(add(3, 5)) # 输出:8

# 结合sorted函数排序

students = [("Alice", 20), ("Bob", 18), ("Charlie", 22)]

# 按年龄排序

sorted_students = sorted(students, key=lambda x: x[1])

print(sorted_students) # 输出:[('Bob', 18), ('Alice', 20), ('Charlie', 22)]

变量作用域:变量的可见范围

变量作用域指的是变量的可见范围,即变量在程序的哪些部分可以被访问。Python 遵循 LEGB 规则来确定变量的作用域:

LEGB 规则详解

  • Local(局部):函数内部定义的变量,仅在函数内部可用,函数执行结束后局部变量会被销毁。
  • Enclosing(嵌套):嵌套函数中,外部函数的变量对内部函数可见,但内部函数不能直接修改外部函数的局部变量(除非使用 nonlocal 关键字)。
  • Global(全局):模块级别定义的变量,在整个模块内都可以使用,函数内部可以访问全局变量,但默认不能修改(除非使用 global 关键字)。
  • Built-in(内置):Python 内置的函数和变量(如 print、len 等),在任何位置都可以使用。

示例代码:


# 全局变量

global_var = "I'm global"

def outer_function():

# 嵌套作用域变量

enclosing_var = "I'm enclosing"

def inner_function():

# 局部变量

local_var = "I'm local"

print(local_var) # 访问局部变量

print(enclosing_var) # 访问嵌套作用域变量

print(global_var) # 访问全局变量

print(len("test")) # 访问内置函数

inner_function()

outer_function()

global 关键字:修改全局变量

当需要在函数内部修改全局变量时,需要使用global关键字声明该变量,明确告知解释器这是一个全局变量。

示例代码:


count = 0 # 全局变量

def increment():

global count # 声明count是全局变量

count += 1

increment()

print(count) # 输出:1

nonlocal 关键字:修改嵌套作用域变量

在嵌套函数中,内部函数默认不能修改外部函数的局部变量。如果需要修改,需使用nonlocal关键字声明该变量。

示例代码:


def outer():

x = 10 # 外部函数的局部变量

def inner():

nonlocal x # 声明x是外部函数的局部变量

x = 20

inner()

print(x) # 输出:20

outer()

闭包与装饰器:函数式编程的高级特性

闭包和装饰器是 Python 函数式编程的重要特性,它们能大幅增强函数的灵活性和功能扩展性。

闭包:携带状态的函数

闭包是指在嵌套函数中,内部函数引用了外部函数的变量,并且外部函数返回内部函数的情况。通过闭包,我们可以创建携带状态的函数,这些状态会在函数调用之间保持。

闭包的基本结构:


def outer_function(outer_var):

def inner_function(inner_var):

return outer_var + inner_var # 引用外部函数变量

return inner_function # 返回内部函数

# 创建闭包实例

closure = outer_function(10)

print(closure(5)) # 输出:15

print(closure(3)) # 输出:13

在上述例子中,outer_function 返回 inner_function 后,outer_var 变量并没有被销毁,而是被 inner_function 携带并保持状态。

装饰器:增强函数功能的利器

装饰器本质上是一个闭包,它接受一个函数作为参数,并返回一个新的函数,用于在不修改原函数代码的情况下增强函数的功能。

装饰器的基本语法使用@符号:


def decorator_function(original_function):

def wrapper_function(*args, **kwargs):

# 增强功能的代码(如日志记录、性能计时等)

print(f"调用函数:{original_function.__name__}")

# 调用原函数

result = original_function(*args, **kwargs)

# 增强功能的代码

print(f"函数调用结束:{original_function.__name__}")

return result

return wrapper_function

@decorator_function

def add(a, b):

return a + b

print(add(3, 5))

# 输出:

# 调用函数:add

# 函数调用结束:add

# 8

装饰器广泛应用于日志记录、权限验证、性能分析等场景,是 Python 中实现 AOP(面向切面编程)的重要方式。

总结

函数是 Python 编程的核心要素,从基础的函数定义、参数传递,到高级的闭包和装饰器,每一个知识点都值得深入掌握。灵活运用各类参数能让函数更具通用性;理解变量作用域能避免常见的变量访问错误;而闭包和装饰器则为函数功能扩展提供了强大工具。

掌握这些知识后,你将能编写出更优雅、更高效、更易维护的 Python 代码,从容应对各种编程挑战。建议在实际开发中多练习、多总结,不断深化对 Python 函数特性的理解和运用。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐