Python函数:让你的代码学会“社交”的终极指南
函数就像代码世界里的社交达人,它们知道何时该说话(接受参数),何时该倾听(返回结果),以及如何在不同场合(作用域)表现得体。
一、函数的“社交技巧”:参数传递的艺术
1.1 位置参数:先来后到的规矩
def introduce(name, age, city): """最基本的参数传递方式,像排队一样讲究顺序""" return f"我叫{name},今年{age}岁,来自{city}"
print(introduce("小明", 25, "北京"))
print(introduce("北京", "小明", 25))
|
小细节:位置参数是函数的最基本要求,调用时必须提供,且顺序不能乱。
1.2 关键字参数:直接点名不排队
print(introduce(age=25, city="上海", name="小红"))
print(introduce("小刚", city="广州", age=30)) print(introduce(name="小李", "深圳", age=28))
|
小贴士:当函数参数很多时,使用关键字参数可读性更强,减少出错概率。
1.3 默认参数:贴心的备胎值
def order_coffee(coffee_type, size="大杯", sugar="正常"): """给参数设置默认值,让调用更灵活""" return f"一杯{size}的{coffee_type},糖度:{sugar}"
print(order_coffee("拿铁"))
print(order_coffee("美式", size="中杯", sugar="无糖"))
|
重要警告:默认参数有个大坑!
def add_item(item, shopping_list=[]): shopping_list.append(item) return shopping_list
print(add_item("苹果")) print(add_item("香蕉"))
def add_item_safe(item, shopping_list=None): if shopping_list is None: shopping_list = [] shopping_list.append(item) return shopping_list
|
1.4 收集参数:来者不拒的社交达人
*args:收集所有位置参数
def party_host(*args): """*args把位置参数打包成元组""" print(f"今晚的客人有:{len(args)}位") for guest in args: print(f"- {guest}")
party_host("小明", "小红", "小刚", "小李")
|
**kwargs:收集所有关键字参数
def create_profile(**kwargs): """**kwargs把关键字参数打包成字典""" profile = {} for key, value in kwargs.items(): profile[key] = value return profile
user = create_profile(name="小王", age=25, job="程序员", hobby="打游戏") print(user)
|
全家福:所有参数一起上
def universal_function(required, *args, default="默认值", **kwargs): """参数界的满汉全席""" print(f"必需参数: {required}") print(f"额外位置参数: {args}") print(f"默认参数: {default}") print(f"额外关键字参数: {kwargs}")
universal_function("必须的", "额外1", "额外2", default="覆盖默认", extra1="补充1", extra2="补充2")
|
1.5 参数解包:把礼物拆开送
def describe_person(name, age, city): return f"{name} ({age}岁, {city})"
print(describe_person("小明", 25, "北京"))
data = ["小红", 30, "上海"] print(describe_person(*data))
info = {"name": "小刚", "age": 28, "city": "广州"} print(describe_person(**info))
|
二、作用域:变量的“社交圈子”
2.1 作用域层次:从村头到全球
global_var = "我是全局变量"
def outer_function(): outer_var = "我是外层变量" def inner_function(): inner_var = "我是内层变量" print(f"内层能看到: {inner_var}") print(f"内层能看到外层: {outer_var}") print(f"内层能看到全局: {global_var}") inner_function() print(f"外层能看到: {outer_var}") print(f"外层能看到全局: {global_var}")
outer_function() print(f"全局能看到: {global_var}")
|
2.2 global:我要改变世界!
counter = 0
def increment(): global counter counter += 1 print(f"当前计数: {counter}")
increment() increment() increment()
|
小心陷阱:没有global会怎样?
x = 10
def confuse(): x = 20 print(f"函数内的x: {x}")
confuse() print(f"函数外的x: {x}")
|
2.3 nonlocal:我只想改变邻居家
def outer(): x = "原始值" def inner(): nonlocal x x = "被修改了" print(f"inner内部: {x}") print(f"修改前: {x}") inner() print(f"修改后: {x}")
outer()
|
重要区别:
global:修改全局作用域的变量
nonlocal:修改外层(非全局)作用域的变量
三、函数嵌套:俄罗斯套娃式的代码
3.1 基本嵌套:函数里的函数
def bank_account(initial_balance): """闭包:一个会"记住"状态的函数""" balance = initial_balance def deposit(amount): nonlocal balance balance += amount return f"存款{amount},当前余额:{balance}" def withdraw(amount): nonlocal balance if amount > balance: return "余额不足!" balance -= amount return f"取款{amount},当前余额:{balance}" def check_balance(): return f"当前余额:{balance}" return {"存钱": deposit, "取钱": withdraw, "查余额": check_balance}
ming_account = bank_account(1000) print(ming_account["查余额"]()) print(ming_account["存钱"](500)) print(ming_account["取钱"](200))
hong_account = bank_account(500) print(hong_account["查余额"]())
|
3.2 装饰器:给函数穿衣服
import time
def timer_decorator(func): """计算函数执行时间的装饰器""" def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"{func.__name__} 执行时间: {end_time - start_time:.4f}秒") return result return wrapper
@timer_decorator def slow_function(): """一个假装很慢的函数""" time.sleep(1) return "任务完成!"
print(slow_function())
|
3.3 lambda函数:匿名的社交恐惧者
def add(x, y): return x + y
add_lambda = lambda x, y: x + y
print(add(3, 5)) print(add_lambda(3, 5))
students = [ {"name": "小明", "score": 85}, {"name": "小红", "score": 92}, {"name": "小刚", "score": 78} ]
sorted_students = sorted(students, key=lambda x: x["score"], reverse=True) for student in sorted_students: print(f"{student['name']}: {student['score']}分")
|
四、实战演练:打造你的瑞士军刀函数
def swiss_knife(data, *processors, default="未处理", **options): """ 一个多功能处理函数 参数: - data: 要处理的数据 - *processors: 多个处理函数 - default: 默认返回值 - **options: 配置选项 """ verbose = options.get('verbose', False) max_retries = options.get('max_retries', 3) if verbose: print(f"开始处理数据,重试次数:{max_retries}") result = data for i, processor in enumerate(processors, 1): try: result = processor(result) if verbose: print(f"第{i}个处理器完成,结果:{result}") except Exception as e: print(f"处理器{i}出错:{e}") return default return result
def double(x): return x * 2
def add_ten(x): return x + 10
def square(x): return x ** 2
result = swiss_knife(5, double, add_ten, square, verbose=True, max_retries=5) print(f"最终结果:{result}")
|
五、总结:函数社交指南
| 特性 |
一句话总结 |
使用场景 |
| 位置参数 |
排队进场,先来后到 |
简单函数,参数顺序明确 |
| 关键字参数 |
凭票入场,对号入座 |
参数多或可选参数多时 |
| 默认参数 |
自带干粮,有备无患 |
参数有常用默认值时 |
| *args |
来者不拒,统统收下 |
不确定需要多少位置参数时 |
| **kwargs |
名字很重要,按名收礼 |
不确定需要什么关键字参数时 |
| global |
我要改变世界! |
需要修改全局变量时 |
| nonlocal |
我只改邻居家 |
闭包中修改外层变量时 |
| 函数嵌套 |
俄罗斯套娃,各玩各的 |
实现装饰器、闭包、工厂函数时 |
记住:好的函数就像好的社交达人,知道何时该严格(参数检查),何时该灵活(默认值),何时该开放(收集参数),何时该保护隐私(作用域隔离)。
现在,让你的Python函数出去社交吧!记得提醒它们:参数要清晰,作用域要明确,嵌套要有度。Happy coding! 🚀
彩蛋:测试你的理解
def mystery(x, y=[]): y.append(x) return y
print(mystery(1)) print(mystery(2)) print(mystery(3, [])) print(mystery(4))
|