大家好,我是正在实战各种 AI 项目的程序员晚枫。
🎬 开篇:理解"函数是一等公民" 你有没有想过,为什么 Python 可以这样写?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def greet (name ): return f"Hello, {name} " say_hello = greet print (say_hello("Alice" )) funcs = [len , str .upper, max ] print (funcs[0 ]("Hello" )) result = map (str .upper, ['hello' , 'world' ]) print (list (result))
这就是函数是一等公民(First-Class Citizen) 的含义:函数可以像普通对象一样被操作。
一等公民的四个权利 在 Python 中,函数拥有以下"权利":
可以赋值给变量 可以作为参数传递 可以作为返回值 可以存储在数据结构中 今天我们就深入理解这个核心概念,掌握函数式编程的精髓。
🎯 函数作为对象 1. 函数赋值给变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def greet (name ): """问候函数""" return f"Hello, {name} " print (type (greet)) say_hello = greet print (say_hello is greet) print (greet("Alice" )) print (say_hello("Bob" )) del greetprint (say_hello("Charlie" ))
2. 函数存储在数据结构中 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 math_ops = [abs , max , min , sum , round ] for op in math_ops: result = op([-1 , 2 , -3 , 4 ]) print (f"{op.__name__} : {result} " ) def add (x, y ): return x + y def subtract (x, y ): return x - y def multiply (x, y ): return x * y def divide (x, y ): return x / y if y != 0 else "Error" operations = { '+' : add, '-' : subtract, '*' : multiply, '/' : divide, } def calculate (x, op, y ): func = operations.get(op) if func: return func(x, y) return "未知操作" print (calculate(10 , '+' , 5 )) print (calculate(10 , '*' , 5 ))
3. 函数作为参数 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 def apply_operation (data, operation ): """对数据应用操作""" return [operation(item) for item in data] numbers = [1 , 2 , 3 , 4 , 5 ] squared = apply_operation(numbers, lambda x: x ** 2 ) cubed = apply_operation(numbers, lambda x: x ** 3 ) negated = apply_operation(numbers, lambda x: -x) print (squared) print (cubed) print (negated) students = [ {'name' : 'Alice' , 'age' : 20 , 'score' : 95 }, {'name' : 'Bob' , 'age' : 19 , 'score' : 87 }, {'name' : 'Charlie' , 'age' : 21 , 'score' : 92 }, ] by_age = sorted (students, key=lambda s: s['age' ]) print ([s['name' ] for s in by_age]) by_score = sorted (students, key=lambda s: s['score' ], reverse=True ) print ([s['name' ] for s in by_score])
4. 函数作为返回值 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 def make_power (n ): """创建求 n 次幂的函数""" def power (x ): return x ** n return power square = make_power(2 ) cube = make_power(3 ) quartic = make_power(4 ) print (square(3 )) print (cube(3 )) print (quartic(3 )) def make_validator (min_val, max_val ): """创建范围验证器""" def validate (value ): return min_val <= value <= max_val return validate is_valid_age = make_validator(0 , 120 ) print (is_valid_age(25 )) print (is_valid_age(150 )) is_valid_score = make_validator(0 , 100 ) print (is_valid_score(95 )) print (is_valid_score(105 ))
🔒 闭包:函数记住它的环境 什么是闭包? 闭包(Closure) 是一个函数,它"记住"了定义时的环境变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def make_multiplier (n ): """创建乘法器""" def multiplier (x ): return x * n return multiplier double = make_multiplier(2 ) triple = make_multiplier(3 ) quadruple = make_multiplier(4 ) print (double(5 )) print (triple(5 )) print (quadruple(5 ))
关键点 :
multiplier 函数"闭包"了外部变量 n即使 make_multiplier 已经执行完毕,n 依然被记住 每个 multiplier 实例都有自己的 n 闭包的三个要素 1 2 3 4 5 6 7 def outer (x ): def inner (y ): return x + y return inner add_5 = outer(5 ) print (add_5(10 ))
查看 closure 变量 1 2 3 4 5 6 7 8 9 10 11 def make_multiplier (n ): def multiplier (x ): return x * n return multiplier double = make_multiplier(2 ) print (double.__code__.co_freevars) print (double.__closure__) print (double.__closure__[0 ].cell_contents)
闭包的实际应用 1. 配置函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def make_url_formatter (base_url, api_key ): """创建 API URL 格式化器""" def format_url (endpoint, **params ): url = f"{base_url} /{endpoint} ?key={api_key} " for key, value in params.items(): url += f"&{key} ={value} " return url return format_url github = make_url_formatter("https://api.github.com" , "gh_xxx" ) weather = make_url_formatter("https://api.weather.com" , "wth_xxx" ) print (github("users" , name="alice" ))print (weather("forecast" , city="beijing" ))
2. 缓存/记忆化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 def memoize (func ): """记忆化装饰器""" cache = {} def wrapper (*args ): if args in cache: print (f"缓存命中: {args} " ) return cache[args] result = func(*args) cache[args] = result return result return wrapper @memoize def fibonacci (n ): """斐波那契数列""" if n < 2 : return n return fibonacci(n - 1 ) + fibonacci(n - 2 ) print (fibonacci(10 )) print (fibonacci(10 ))
3. 回调函数 1 2 3 4 5 6 7 8 9 10 11 12 def make_callback (prefix ): """创建带前缀的回调函数""" def callback (message ): print (f"[{prefix} ] {message} " ) return callback info_callback = make_callback("INFO" ) error_callback = make_callback("ERROR" ) info_callback("服务启动" ) error_callback("连接失败" )
🧩 高阶函数 内置高阶函数 map:映射 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 numbers = [1 , 2 , 3 , 4 , 5 ] squared = map (lambda x: x ** 2 , numbers) print (list (squared)) str_numbers = map (str , numbers) print (list (str_numbers)) a = [1 , 2 , 3 ] b = [10 , 20 , 30 ] sums = map (lambda x, y: x + y, a, b) print (list (sums)) squared = [x ** 2 for x in numbers]
filter:过滤 1 2 3 4 5 6 7 8 9 10 11 12 13 14 numbers = range (10 ) evens = filter (lambda x: x % 2 == 0 , numbers) print (list (evens)) texts = ['hello' , '' , 'world' , None , 'python' , '' ] valid = filter (None , texts) print (list (valid)) evens = [x for x in numbers if x % 2 == 0 ]
reduce:归约 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 from functools import reducenumbers = [1 , 2 , 3 , 4 , 5 ] total = reduce(lambda x, y: x + y, numbers) print (total) product = reduce(lambda x, y: x * y, numbers) print (product) maximum = reduce(lambda x, y: x if x > y else y, numbers) print (maximum) total = reduce(lambda x, y: x + y, numbers, 100 ) print (total) nested = [[[1 , 2 ], [3 , 4 ]], [[5 , 6 ], [7 , 8 ]]] flat = reduce(lambda x, y: x + y, reduce(lambda x, y: x + y, nested)) print (flat)
sorted、min、max 的 key 参数 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 words = ['banana' , 'pie' , 'Washington' , 'book' ] sorted_words = sorted (words, key=str .lower) print (sorted_words) by_length = sorted (words, key=len ) print (by_length) by_length_desc = sorted (words, key=len , reverse=True ) print (by_length_desc) students = [ {'name' : 'Alice' , 'score' : 95 }, {'name' : 'Bob' , 'score' : 87 }, {'name' : 'Charlie' , 'score' : 92 }, ] by_score = sorted (students, key=lambda s: s['score' ], reverse=True ) print ([s['name' ] for s in by_score]) numbers = [3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 ] print (min (numbers)) print (max (numbers)) words = ['apple' , 'pie' , 'banana' ] print (min (words, key=len )) print (max (words, key=len ))
🎭 lambda 表达式 lambda 语法 1 2 3 4 5 6 7 add = lambda x, y: x + y print (add(3 , 4 )) def add (x, y ): return x + y
lambda 的使用场景 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 students = [('Alice' , 95 ), ('Bob' , 87 ), ('Charlie' , 92 )] sorted_students = sorted (students, key=lambda s: s[1 ], reverse=True ) print (sorted_students) numbers = range (20 ) evens = list (filter (lambda x: x % 2 == 0 , numbers)) print (evens) squares = list (map (lambda x: x ** 2 , range (5 ))) print (squares) d = {'a' : 3 , 'b' : 1 , 'c' : 2 } sorted_items = sorted (d.items(), key=lambda item: item[1 ]) print (sorted_items) buttons = [ {'text' : 'Save' , 'action' : lambda : print ('保存' )}, {'text' : 'Cancel' , 'action' : lambda : print ('取消' )}, ] for button in buttons: button['action' ]()
lambda 的局限性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 result = map (lambda x: x ** 2 if x > 0 else 0 , range (-5 , 5 )) def square_if_positive (x ): if x > 0 : return x ** 2 return 0 result = map (square_if_positive, range (-5 , 5 ))
📊 性能对比 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 import timeitnumbers = list (range (10000 )) list_comp = timeit.timeit('[x**2 for x in numbers]' , globals =globals (), number=1000 ) map_func = timeit.timeit('list(map(lambda x: x**2, numbers))' , globals =globals (), number=1000 ) print (f"列表推导式: {list_comp:.4 f} s" )print (f"map+lambda: {map_func:.4 f} s" )upper_list = timeit.timeit('[s.upper() for s in strings]' , globals =globals (), setup="strings = ['hello'] * 1000" , number=1000 ) upper_map = timeit.timeit('list(map(str.upper, strings))' , globals =globals (), setup="strings = ['hello'] * 1000" , number=1000 ) print (f"列表推导式: {upper_list:.4 f} s" )print (f"map: {upper_map:.4 f} s" )
⚠️ 避坑指南 陷阱 1:闭包中的延迟绑定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 def make_multipliers (): funcs = [] for i in range (5 ): def multiplier (x ): return x * i funcs.append(multiplier) return funcs multipliers = make_multipliers() print ([m(10 ) for m in multipliers]) def make_multipliers_fixed (): funcs = [] for i in range (5 ): def multiplier (x, n=i ): return x * n funcs.append(multiplier) return funcs multipliers = make_multipliers_fixed() print ([m(10 ) for m in multipliers])
陷阱 2:lambda 中的循环变量 1 2 3 4 5 6 7 funcs = [lambda : i for i in range (5 )] print ([f() for f in funcs]) funcs = [lambda i=i: i for i in range (5 )] print ([f() for f in funcs])
陷阱 3:修改闭包变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def counter (): count = 0 def inc (): count += 1 return count return inc def counter_fixed (): count = 0 def inc (): nonlocal count count += 1 return count return inc c = counter_fixed() print (c()) print (c()) print (c())
🎯 本讲总结 通过本讲,我们掌握了:
知识点 核心要点 函数是一等公民 可赋值、存储、传递、返回 高阶函数 map、filter、reduce、sorted 闭包 函数记住定义时的环境变量 lambda 匿名函数,用于简单场景 延迟绑定 闭包中的常见陷阱,用默认参数解决 nonlocal 在闭包中修改外部变量
记住这句话 :
函数是一等公民,这让 Python 支持函数式编程,能写出更灵活、更优雅的代码。
📚 推荐教材 《Python 编程从入门到实践(第 3 版)》 | 《流畅的 Python(第 2 版)》 | 《CPython 设计与实现》
学习路线: 零基础 → 《从入门到实践》 → 《流畅的 Python》 → 本门课程 → 《CPython 设计与实现》
🎓 加入《流畅的 Python》直播共读营 学到这里,如果你想系统吃透这本书——欢迎加入我的直播共读课。
每周直播精讲,逐章拆解核心知识点 专属学习群,随时答疑交流 试运营特惠:499 元 → 299 元 👉 【立即报名《流畅的 Python》共读课】 :https://mp.weixin.qq.com/s/ivHJwn1nNx5ug4TFrapvGg
🔗 课程导航 ← 上一讲:文本与字节 | 下一讲:装饰器详解 →
💬 联系我 主营业务 :AI 编程培训、企业内训、技术咨询
🎓 AI 编程实战课程 想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!