Python(九):第八章: 函数知识总结

第八章: 函数知识总结

8.1 内置函数

数学和数值计算

1
2
3
4
5
6
7
8
abs(-2)           # 绝对值:2
divmod(20, 3) # 商和余数:(6, 2)
round(4.51) # 四舍五入:5
pow(10, 2) # 幂运算:100
pow(10, 2, 3) # 幂运算后取余:1
sum([1, 2, 3]) # 求和:6
min(5, 3, 9) # 最小值:3
max(7, 3, 15) # 最大值:15

进制转换

1
2
3
bin(10)           # 转二进制:'0b1010'
oct(10) # 转八进制:'0o12'
hex(10) # 转十六进制:'0xa'

字符编码

1
2
3
4
bytes("你好", encoding="utf-8")  # 字符串转字节:b'\xe4\xbd\xa0\xe5\xa5\xbd'
bytearray("hi", encoding='utf-8') # 可变字节数组
ord('a') # 字符码位:97
chr(65) # 码位对应字符:'A'

反射函数

1
2
3
4
5
dir(obj)          # 查看对象的所有属性
hasattr(obj, 'attr') # 检查对象是否有属性
getattr(obj, 'attr') # 获取对象属性
setattr(obj, 'attr', value) # 设置对象属性
delattr(obj, 'attr') # 删除对象属性

其他常用内置函数

1
2
3
4
5
len("hello")      # 获取长度:5
isinstance(obj, type) # 类型检查
issubclass(cls1, cls2) # 检查类继承关系
id(obj) # 获取对象内存地址
type(obj) # 获取对象类型

8.2 函数定义与调用

1
2
3
4
5
6
7
8
# 基本函数定义
def function_name(parameters):
"""文档字符串:描述函数功能"""
# 函数体
return value # 可选

# 调用函数
result = function_name(arguments)

8.3 函数参数

位置参数

1
2
3
4
def test(x, y, z):
print(x, y, z)

test(1, 2, 3) # 必须按顺序提供所有参数

关键字参数

1
2
3
4
def test(x, y, z):
print(x, y, z)

test(y=1, x=2, z=3) # 通过参数名指定,顺序可变

默认参数

1
2
3
4
5
def test(x, y, z=2):
print(x, y, z)

test(1, 2) # z使用默认值2
test(1, 2, 3) # 覆盖默认值

可变参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# *args:接收多余的位置参数,形成元组
def test(x, *args):
print(x)
print(args)

test(1, 2, 3, 4) # x=1, args=(2, 3, 4)

# **kwargs:接收多余的关键字参数,形成字典
def test(x, **kwargs):
print(x)
print(kwargs)

test(x=1, y=2, z=3) # x=1, kwargs={'y': 2, 'z': 3}

# 混合使用
def test(x, *args, **kwargs):
print(x, args, kwargs)

test(1, 2, 3, y=4, z=5) # x=1, args=(2, 3), kwargs={'y': 4, 'z': 5}

8.4 作用域与命名空间

名称空间

Python 有三层名称空间:

  1. 内置名称空间:Python 解释器启动时创建,包含内置函数
  2. 全局名称空间:模块级别创建,包含模块中定义的变量
  3. 局部名称空间:函数调用时创建,包含函数内部变量

LEGB 规则

变量查找顺序:

  1. Local:局部作用域
  2. Enclosing:外部嵌套函数作用域
  3. Global:全局作用域
  4. Built-in:内置作用域

作用域修饰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# global:声明变量为全局变量
x = 10
def modify_global():
global x
x = 20

modify_global()
print(x) # 输出:20

# nonlocal:访问外层函数变量
def outer():
x = 10
def inner():
nonlocal x
x = 20
inner()
print(x) # 输出:20

outer()

8.5 高阶函数特性

函数作为参数传递

1
2
3
4
5
6
7
def apply_function(func, value):
return func(value)

def square(x):
return x ** 2

result = apply_function(square, 5) # 结果:25

函数作为返回值

1
2
3
4
5
6
7
8
9
10
def get_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier

double = get_multiplier(2)
triple = get_multiplier(3)

print(double(5)) # 结果:10
print(triple(5)) # 结果:15

函数存储在数据结构中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def check_balance():
print("查询账户余额")


def transfer_money():
print("转账服务")


def deposit():
print("存款服务")


def withdraw():
print("取款服务")


def update_info():
print("更新个人信息")


# 存储在列表中 - 通过数字选择功能
function_list = [check_balance, transfer_money, deposit, withdraw, update_info]

# 存储在字典中 - 通过命令选择功能
function_dict = {
'balance': check_balance,
'transfer': transfer_money,
'deposit': deposit,
'withdraw': withdraw,
'update': update_info
}


def bank_system():
print("\n欢迎使用银行服务系统")
print("您可以通过数字或命令使用服务")

while True:
print("\n=== 银行服务菜单 ===")
print("1. 查询账户余额")
print("2. 转账服务")
print("3. 存款服务")
print("4. 取款服务")
print("5. 更新个人信息")
print("0. 退出系统")
print("\n或者输入命令:balance, transfer, deposit, withdraw, update, exit")

choice = input("\n请输入您的选择(数字或命令): ")

if choice == "0" or choice.lower() == "exit":
print("感谢使用银行服务系统,再见!")
break

# 通过数字调用列表中的函数
if choice.isdigit():
index = int(choice) - 1
if 0 <= index < len(function_list):
function_list[index]()
else:
print("无效的数字选择,请重新输入")

# 通过命令调用字典中的函数
elif choice.lower() in function_dict:
function_dict[choice.lower()]()
else:
print("无效的命令,请重新输入")


# 启动银行系统
if __name__ == "__main__":
bank_system()

高阶函数设计模式

高阶函数是函数式编程的核心概念,它们接受其他函数作为参数或返回函数作为结果。

函数组合模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def compose(*functions):
"""将多个函数组合成一个函数
compose(f, g, h)(x) 等价于 f(g(h(x)))
"""
# 定义一个内部函数,接收一个参数x
def inner(x):
# 初始化结果为输入值x
result = x
# 反转函数列表,确保执行顺序是从右到左
# 例如compose(f, g, h)(x)会按h(x),然后g(结果),最后f(结果)的顺序执行
for f in reversed(functions):
# 将上一步的结果作为当前函数的输入
result = f(result)
# 返回最终结果
return result
# 返回内部函数,形成闭包
return inner

# 示例:文本处理管道
def remove_punctuation(text):
import string
# 去除标点符号
# str.maketrans创建一个转换表,将所有标点符号映射为空
# string.punctuation包含所有标点符号
return text.translate(str.maketrans('', '', string.punctuation))

def lowercase(text):
# 将文本转换为小写
return text.lower()

def remove_whitespace(text):
# 先用split()将文本按空白字符分割成列表
# 然后用join重新连接,确保单词之间只有一个空格
return ' '.join(text.split())

# 组合函数
# 这里创建了一个处理管道,按照从右到左的顺序执行:
# 1. 首先remove_punctuation去除标点
# 2. 然后lowercase转小写
# 3. 最后remove_whitespace规范化空白
process_text = compose(remove_whitespace, lowercase, remove_punctuation)

# 使用函数管道
text = "Hello, World! This is an Example."
# 执行过程:
# 1. remove_punctuation: "Hello World This is an Example"
# 2. lowercase: "hello world this is an example"
# 3. remove_whitespace: "hello world this is an example"
print(process_text(text)) # "hello world this is an example"

部分应用

部分应用是预先指定一个函数的部分参数,创建一个新的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from functools import partial

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

# 创建一个计算平方的函数
square = partial(power, exponent=2)
print(square(4)) # 16

# 创建一个计算立方的函数
cube = partial(power, exponent=3)
print(cube(3)) # 27

# 创建一个计算2的幂的函数
powers_of_two = partial(power, 2)
print(powers_of_two(8)) # 256 (2^8)

8.6 匿名函数(lambda)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 # 基本语法
lambda 参数: 表达式

# 示例
add = lambda x, y: x + y
print(add(5, 3)) # 结果:8

# 在高阶函数中使用
numbers = [1, 2, 3, 4, 5]
squares = map(lambda x: x**2, numbers)
print(list(squares)) # 结果:[1, 4, 9, 16, 25]

# 在排序中使用
words = ['apple', 'banana', 'cherry']
sorted_words = sorted(words, key=lambda x: len(x))

8.7 闭包函数

闭包是指内部函数引用了外部函数的变量,并且外部函数返回了内部函数。

1
2
3
4
5
6
7
8
9
10
11
12
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment

my_counter = counter()
print(my_counter()) # 1
print(my_counter()) # 2
print(my_counter()) # 3

8.8 递归函数

递归是一种函数在执行过程中调用自身的编程技巧。

1
2
3
4
5
6
7
8
9
10
# 阶乘递归实现
def factorial(n):
# 基本情况(递归终止条件)
if n == 0 or n == 1:
return 1
# 递归调用
else:
return n * factorial(n-1)

print(factorial(5)) # 120

递归的关键要素

  1. 基本情况(终止条件):必须定义何时停止递归
  2. 递归关系:将问题分解为更小的子问题

递归深度限制

1
2
3
import sys
print(sys.getrecursionlimit()) # 默认递归深度(通常为1000)
sys.setrecursionlimit(3000) # 调整递归深度限制

递归案例:列表扁平化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def flatten_list(nested_list):
"""递归扁平化嵌套列表"""
result = []
for item in nested_list:
if isinstance(item, list):
# 递归处理子列表
result.extend(flatten_list(item))
else:
# 基本情况:添加非列表元素
result.append(item)
return result

# 测试
nested = [1, [2, 3], [4, [5, 6], 7], 8, [9, [10, [11, 12]]]]
print(flatten_list(nested)) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

8.9 装饰器

装饰器是一种特殊的函数,用于修改其他函数的功能。

基本装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import time


def count_time(func):
def wrapper(*args,**kwargs):
start_time = time.time()
result = func(*args,**kwargs)
end_time = time.time()
print("总共耗时:",end_time-start_time)
return result
return wrapper

@count_time # 在这里装饰器相当于 count_time = count_time(test)
def test():
sum = 0
for i in range(10000000):
sum += i
return sum


result = test()
print(result)

带参数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import time

def repeat(times):
def count_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = None
for i in range(times):
result = func(*args, **kwargs)
print(f"第{i+1}次执行完成")
end_time = time.time()
print("总共耗时:", end_time - start_time)
return result
return wrapper
return count_time

@repeat(3) # 重复执行3次
def count_sum():
sum = 0
for i in range(10000000):
sum += i
return sum


result = count_sum()
print(result)

保留原函数元数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from functools import wraps


def decorator(func):
@wraps(func) # 保留原函数的元数据
def wrapper(*args, **kwargs):
"""包装函数"""
print("函数执行前")
result = func(*args, **kwargs)
print("函数执行后")
return result

return wrapper


@decorator
def say_hello(name):
"""打招呼函数"""
print(f"Hello, {name}!")

# __name__属性为函数的名称,但默认情况下,被装饰器装饰了的函数的名称会变成wrapper,可以通过wraps装饰器保留原函数的元数据来解决这个问题。
print(say_hello.__name__) # say_hello (而不是wrapper)
# 同理,__doc__属性为函数的文档字符串,可以通过wraps装饰器保留原函数的元数据来解决这个问题。
print(say_hello.__doc__) # 打招呼函数

装饰器叠加

1
2
3
4
5
6
7
8
@decorator1
@decorator2
@decorator3
def function():
pass

# 等价于
function = decorator1(decorator2(decorator3(function)))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 执行顺序示例
def decorator1(func):
def wrapper(*args, **kwargs):
print("装饰器1开始")
result = func(*args, **kwargs)
print("装饰器1结束")
return result
return wrapper

def decorator2(func):
def wrapper(*args, **kwargs):
print("装饰器2开始")
result = func(*args, **kwargs)
print("装饰器2结束")
return result
return wrapper

@decorator1
@decorator2
def greet():
print("问候函数执行")

greet()
# 输出:
# 装饰器1开始
# 装饰器2开始
# 问候函数执行
# 装饰器2结束
# 装饰器1结束

装饰器工厂

创建能够接受多种配置的通用装饰器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import functools
import time


def retry(exceptions, tries=4, delay=3, backoff=2, logger=None):
"""可配置的重试装饰器

Args:
exceptions: 要捕获的异常类或异常类元组
tries: 最大尝试次数
delay: 初始延迟时间(秒)
backoff: 重试间隔的增长因子
logger: 用于记录警告的日志对象
"""

def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
mtries, mdelay = tries, delay
last_exception = None

while mtries > 0:
try:
return func(*args, **kwargs)
except exceptions as e:
last_exception = e
msg = f"{func.__name__}: 重试 {tries - mtries + 1}/{tries} 失败: {e}"
if logger:
logger.warning(msg)
else:
print(msg)

# 延迟后重试
time.sleep(mdelay)
mdelay *= backoff
mtries -= 1

# 所有尝试都失败
raise last_exception

return wrapper

return decorator


# 使用示例
import requests

@retry(exceptions=(requests.RequestException, ConnectionError),
tries=3, delay=1, backoff=2)
def fetch_url(url):
"""获取URL内容,失败时自动重试"""
response = requests.get(url, timeout=2)
response.raise_for_status()
return response.text


# 调用示例
try:
content = fetch_url("https://this-website-does-not-exist-123456789.com")
print(content)
except requests.RequestException as e:
print(f"获取内容失败: {e}")