【Python】函数详细介绍,附代码详解(参数类型、返回值、作用域、高阶函数、闭包、装饰器、生成器、递归等)

文章目录

  • 1. 定义
  • 2. 函数参数类型
    • 2.1 位置参数
    • 2.2 默认参数
    • 2.3 关键字参数
    • 2.4 可变参数
      • 2.4.1 *args
      • 2.4.2 **kwargs
      • 2.4.3 使用参数的顺序
    • 2.5 仅限位置参数(Python 3.8 以上版本)
    • 2.6 仅限关键字参数
  • 3. 返回值
  • 4. 作用域和变量访问
  • 5. 匿名函数 lambda
  • 6. 高阶函数
    • 6.1 map()
    • 6.2 filter()
    • 6.3 sorted()
    • 6.4 reduce()
  • 7. 闭包
  • 8. 装饰器(Decorator)
  • 9. 生成器函数
  • 10. 递归函数
  • 11. 函数文档与注释
  • 12. 总结
    • 12.1 函数优势
    • 12.2 灵活使用

1. 定义

  • 函数是一段可重复调用的代码块,用于封装特定功能,提高代码复用性和可维护性
# def 函数名(参数1, 参数2, ...):
#     """函数文档字符串(可选)"""
#     # 函数体
#     return 返回值(可选)
  • 当没有 return 语句,函数默认返回 None
 def add(a, b):
    """计算两个数的和"""
    result = a + b
     return result

 # 调用函数
 sum_result = add(3, 5)
 print(sum_result)  # 输出: 8

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
8
Process finished with exit code 0

2. 函数参数类型

2.1 位置参数

  • 参数顺序传递值
def greet(name, message):
    print(f"{message}, {name}!")
    
greet("Echo", "Hello")  # 输出: Hello, Echo!

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
Hello, Echo!

Process finished with exit code 0

2.2 默认参数

  • 参数可设置默认值,调用函数时如果没有提供该参数的值,则使用默认值
def greet(name, age=18):
    print(f"Hello, {name}! You are {age} years old.")

greet("Echo")  
# 输出: Hello, Echo! You are 18 years old.

greet("Echo慧", 24)
# 输出: Hello, Echo慧! You are 24 years old.

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
Hello, Echo! You are 18 years old.
Hello, Echo慧! You are 24 years old.

Process finished with exit code 0

2.3 关键字参数

  • 通过参数名指定值,可打乱顺序,不需要按照参数定义的顺序传递
def greet(name, message):
    print(f"{message}, {name}!")

greet('Hello','Echo') # 输出:Echo,Hello!
greet(message='Hello',name='Echo')  # 输出: Hello, Echo!

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
Echo, Hello!
Hello, Echo!

Process finished with exit code 0

2.4 可变参数

2.4.1 *args

  • *args:接收任意数量的位置参数,这些参数以 元组 形式被打包
def sum_numbers(*args):
    total = 0
    for num in args:
        total += num
    return total

result = sum_numbers(1, 2, 3, 4, 5)
print(result)  # 输出: 15

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
15

Process finished with exit code 0

  • *args 可以和普通的位置参数结合使用,但 *args 必须放在普通位置参数之后
def print_info(name, *args):
    print(f"Name: {name}")
    print("Additional arguments:", args)

print_info("Echo", "girl", 24, "Shang Hai")

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
Name: Echo
Additional arguments: (‘girl’, 24, ‘Shang Hai’)

Process finished with exit code 0

2.4.2 **kwargs

  • **kwargs:接收任意数量的关键字参数,这些参数以 字典 形式被打包
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Echo", age=24, city="Shang Hai") # 输出:name:Echo age:24 city:Shang Hai

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
name: Echo
age: 24
city: Shang Hai

Process finished with exit code 0

  • **kwargs 可以和普通位置参数、*args 结合使用,但 **kwargs 必须放在最后
def func(name, *args, **kwargs):
    print(name)
    print(args)
    print(kwargs)

func("Echo", 1, 2, 3, age="24", city="Shang Hai",hobby="Reading", job="Engineer")

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
Echo
(1, 2, 3)
{‘age’: ‘24’, ‘city’: ‘Shang Hai’, ‘hobby’: ‘Reading’, ‘job’: ‘Engineer’}

Process finished with exit code 0

2.4.3 使用参数的顺序

  • 普通位置参数在前,*args 其次,**kwargs 最后
  • 使用 *** 对可迭代对象和字典进行解包,将它们作为参数传递给函数

2.5 仅限位置参数(Python 3.8 以上版本)

  • 使用 / 分隔符限制某些参数必须通过位置传递
  • 斜杠 / 之前的参数为仅限位置参数
def func(a, /, b, c):
    print(a, b, c)

func(1, 2, c=3)  # 正确
func(1, b=2, c=3)  # 正确
func(a=1, b=2, c=3)  # 错误:a 必须是位置参数

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
1 2 3
1 2 3
Traceback (most recent call last):
File “D:\PycharmProjects\pythonProject-test.py”, line 6, in
func(a=1, b=2, c=3) # 错误:a 必须是位置参数
^^^^^^^^^^^^^^^^^^
TypeError: func() got some positional-only arguments passed as keyword arguments: ‘a’

Process finished with exit code 1

2.6 仅限关键字参数

  • 使用 * 分隔符限制某些参数必须通过关键字传递
def func(a, *, b, c):
    print(a, b, c)

func(1, b=2, c=3)  # 正确
func(1, 2, 3)      # 错误:b 和 c 必须是关键字参数

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
1 2 3
Traceback (most recent call last):
File “D:\PycharmProjects\pythonProject-test.py”, line 5, in
func(1, 2, 3) # 错误:b 和 c 必须是关键字参数
^^^^^^^^^^^^
TypeError: func() takes 1 positional argument but 3 were given

Process finished with exit code 1

3. 返回值

  • 使用 return 语句返回一个或多个值
  • 如果返回多个值,这些值会被打包成一个元组
  • 无 return 语句时,函数默认返回 None
def divide(a, b):
    return a // b, a % b

quotient, remainder = divide(10, 3)
print(quotient, remainder)  # 输出: 3 1

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
3 1

Process finished with exit code 0

4. 作用域和变量访问

  • 全局变量-全局作用域-Global:在函数外部定义的变量具有全局作用域,可以在整个程序中访问
  • 局部变量-局部作用域-Local:在函数内部定义的变量具有局部作用域,只能在函数内部访问
  • 嵌套作用域-Nonlocal:在嵌套函数中修改外层函数的变量,需用 nonlocal 声明
  • 如果需要在函数内部修改全局变量,可以使用global 关键字
x = 10  # 全局变量

def outer():
    y = 20  # outer 的局部变量
    def inner():
        nonlocal y  # 声明引用外层变量
        global x    # 声明引用全局变量
        y += 1
        x += 1
    inner()
    print(x, y)  # 输出: 11 21

outer()
print(x) # 输出: 11
# print(y) # 报错,无法在函数外部访问局部变量

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
11 21
11

Process finished with exit code 0

5. 匿名函数 lambda

  • 用于定义简单的单行函数
  • 语法:

lambda 参数列表: 表达式

lambda:定义匿名函数关键字。 参数列表:与普通函数的参数列表类似,可以包含零个或多个参数,多个参数之间用逗号分隔
表达式:函数的返回值,匿名函数只能有一个表达式,不能包含多条语句

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

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
25

Process finished with exit code 0

  • 常用于排序、过滤等场景
data = [("Test1", 25), ("Test2", 20), ("Test3", 30)]
data.sort(key=lambda x: x[1])  # 按年龄排序
print(data) # 输出: [('Test2', 20), ('Test1', 25), ('Test3', 30)]

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
[(‘Test2’, 20), (‘Test1’, 25), (‘Test3’, 30)]

Process finished with exit code 0

6. 高阶函数

  • 接受函数作为参数或返回函数的函数
  • 常见高阶函数:map()、filter()、reduce()、sorted()

6.1 map()

  • map():对可迭代对象中的每个元素应用指定的函数,并返回一个新的可迭代对象
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # 输出: [1, 4, 9, 16]

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
[1, 4, 9, 16]

Process finished with exit code 0

6.2 filter()

  • filter():过滤可迭代对象中的元素,返回一个包含满足指定条件元素的新可迭代对象
numbers = [1, 2, 3, 4]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)    # 输出: [2, 4]

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
[2, 4]

Process finished with exit code 0

6.3 sorted()

  • sorted():对可迭代对象进行排序,并返回一个新的已排序列表
numbers = [5, 2, 1, 4, 3]
obj = sorted(numbers)
print(obj)

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
[1, 2, 3, 4, 5]

Process finished with exit code 0

6.4 reduce()

  • reduce():累积计算(需导入 functools)
numbers = [1, 2, 3, 4]
from functools import reduce
sum_all = reduce(lambda a, b: a + b, numbers)
print(sum_all)  # 输出: 10

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
10

Process finished with exit code 0

7. 闭包

  • 嵌套函数可以捕获并记住外层函数的变量(即使外层函数已执行完毕)
  • 当一个内部函数引用了外部函数的局部变量,且外部函数将这个内部函数作为返回值返回时,就形成了闭包
# outer_function 是外部函数,它接受一个参数 x
# inner_function 是内部函数,它接受一个参数 y,并且引用了外部函数的变量 x
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

# 创建闭包
closure = outer_function(10) # 返回了一个闭包对象 closure = 10 + y

# 调用闭包
result = closure(5)
print(result)  # 输出: 15

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
15

Process finished with exit code 0

8. 装饰器(Decorator)

  • 用于在不修改原函数代码的前提下,增强函数功能
  • 本质是高阶函数,接受函数作为参数并返回新函数
def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            results = []
            for _ in range(n):
                result = func(*args, **kwargs) # 调用被装饰函数
                results.append(result)
            return results
        return wrapper
    return decorator

@repeat(3)  # 等价于 greet = repeat(3)(greet)
def greet(name):
    print(f"Hello, {name}!") # 每次调用都会执行打印
    return f"Greeted {name}"

results = greet("Echo")
print(results)

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
Hello, Echo!
Hello, Echo!
Hello, Echo!
[‘Greeted Echo’, ‘Greeted Echo’, ‘Greeted Echo’]

Process finished with exit code 0

代码解释:

1.装饰器初始化
@repeat(3) 会先执行 repeat(3),返回 decorator 函数。
decorator(greet) 接收原 greet 函数,返回 wrapper 函数。
最终 greet 被替换为 wrapper 函数。
2.函数调用流程
当调用 greet(“Echo”) 时,实际调用的是 wrapper(“Echo”)。
wrapper 会循环 3 次,每次调用原 greet(“Echo”):
每次调用会执行 print(f"Hello, Echo!“)(打印一次)。
收集返回值 f"Greeted Echo”。
3.输出结果
前 3 行:屏幕打印(执行 3 次 print),每次调用 greet 函数时打印的问候语
最后一行:返回值 results(列表包含 3 个返回值),收集了 3 次调用返回值的列表

9. 生成器函数

  • 使用 yield 关键字逐步生成值,而非一次性返回所有结果
def count_up_to(n):
    count = 1
    while count <= n:
        yield count
        count += 1

gen = count_up_to(3)
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
1
2
3

Process finished with exit code 0

关于生成器进一步详解,可参考以下博文:
【Python】迭代器与生成器详解,附代码(可迭代对象、定义、实现方式、区别、使用场景)

10. 递归函数

  • 函数调用自身来解决问题(需注意终止条件
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

print(factorial(5))  # 输出: 120

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
120

Process finished with exit code 0

11. 函数文档与注释

  • 使用 文档字符串(Docstring) 描述函数功能
  • 可通过 help(函数名)函数名.doc 查看
def multiply(a, b):
    """返回两个数的乘积。

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

    Returns:
        int/float: a 和 b 的乘积
    """
    return a * b

print(help(multiply))  # 显示文档内容

12. 总结

12.1 函数优势

  • 代码复用:避免重复代码。
  • 模块化设计:将复杂任务分解为小功能块。
  • 可读性:通过命名和文档提高代码理解性。
  • 维护性:修改功能只需调整函数内部逻辑。

12.2 灵活使用

  • 灵活使用装饰器、闭包、生成器简化代码。
  • 合理选择参数类型和返回值结构
  • 通过递归和函数式编程处理复杂逻辑

你可能感兴趣的:(Python学习,python,开发语言,函数,详解,学习)