今天我们要一起探索的是Python世界中的一块基石——函数!想象一下,像魔术师一样,轻轻一挥手,复杂的任务就被封装成简洁的命令,这就是函数的魅力。下面,让我们用最接地气的方式,揭开它的神秘面纱,掌握那些让代码飞起来的20个小技巧。
1. 基础中的基础:Hello, Function!
1
| def say_hello(name="World"):<br> print(f"Hello, {name}!")<br><br>say_hello("Pythonista") <em># 输出: Hello, Pythonista!</em> |
2. 参数传递:位置VS关键字
1
| def greet(firstName, lastName):<br> print(f"Hi, I'm {firstName} {lastName}")<br><br>greet(lastName="Smith", firstName="John") <em># 明确指定参数名</em> |
- 小贴士:通过名字指定参数,让代码更易读,特别是参数多时。
3. *args 和 **kwargs:无限参数的秘密
1
| def super_greet(*names): <em># *args 收集位置参数</em><br> for name in names:<br> print(f"Hello, {name}!")<br> <br>super_greet("Alice", "Bob", "Charlie") <em># 多个名字一次性处理</em><br><br>def versatile_greet(**details): <em># **kwargs 收集关键字参数</em><br> for key, value in details.items():<br> print(f"{key.title()}: {value}")<br><br>versatile_greet(age=25, city="New York") <em># 关键信息一网打尽</em> |
- 神奇之处:
和
让你的函数可以接受任意数量的参数,超级灵活!
4. 返回值不只是一个
1
| def multiple_returns():<br> return "Success", 200<br><br>result, status = multiple_returns()<br>print(result, status) <em># 输出: Success 200</em> |
- 多才多艺:函数可以返回多个值,其实是以元组的形式返回的。
5. 文档字符串:让代码会说话
1
| def calculate_area(radius):<br> """<br> 计算圆的面积。<br> <br> 参数:<br> radius (float): 圆的半径<br> <br> 返回:<br> float: 圆的面积<br> """<br> import math<br> return math.pi * radius**2<br><br>print(calculate_area.__doc__) <em># 查看文档字符串</em> |
- 文明交流:良好的文档字符串是团队合作的润滑剂,也是自我复习的好帮手。
6. 默认参数的坑
1
| def append_to_list(item, my_list=[]):<br> my_list.append(item)<br> return my_list<br><br>print(append_to_list(1)) <em># [1]</em><br>print(append_to_list(2)) <em># 注意!这里会是 [1, 2],不是预期的 [2]</em> |
- 警告:默认参数在函数定义时就初始化了,多次调用时会保留之前的值,小心这个陷阱。
7. 变量作用域:谁能访问我?
1
| x = "global"<br><br>def scope_test():<br> x = "local"<br> print(x) <em># local</em><br><br>scope_test()<br>print(x) <em># global</em> |
- 名字游戏:在函数内部定义的变量默认是局部的,不会影响到外部的同名变量。
8. 非局部变量的修改
1
| y = 10<br><br>def modify_outer():<br> global y <em># 告诉Python你想修改外部的y</em><br> y = 20<br><br>modify_outer()<br>print(y) <em># 输出: 20</em> |
- 特权操作:使用
关键字可以让函数内部修改全局变量,但要谨慎使用。
9. 闭包:函数内的函数
1
| def counter():<br> count = 0<br> def increment():<br> nonlocal count<br> count += 1<br> return count<br> return increment<br><br>my_counter = counter()<br>print(my_counter()) <em># 1</em><br>print(my_counter()) <em># 2</em> |
- 内外有别:闭包允许内部函数访问并修改外部函数的变量,而外部函数返回的是内部函数的引用。
10. 装饰器:给函数穿上花衣
1
| def my_decorator(func):<br> def wrapper():<br> print("Something is happening before the function is called.")<br> func()<br> print("Something is happening after the function is called.")<br> return wrapper<br><br>@my_decorator<br>def say_hello():<br> print("Hello!")<br><br>say_hello() |
- 装饰生活,装饰函数:装饰器是Python的一大特色,它可以在不修改原函数代码的情况下增加新功能。
高级使用场景
11. 递归:自己调用自己的艺术
1
| def factorial(n):<br> if n == 1:<br> return 1<br> else:<br> return n * factorial(n-1)<br><br>print(factorial(5)) <em># 输出: 120</em> |
- 无限循环的智慧:递归是解决某些问题的强大工具,但要注意避免无限循环,确保有一个清晰的终止条件。
12. 匿名函数lambda:简洁之美
1
| double = lambda x: x * 2<br>print(double(5)) <em># 输出: 10</em><br><br>squared = lambda x: x**2<br>numbers = [1, 2, 3]<br>print(list(map(squared, numbers))) <em># 输出: [1, 4, 9]</em> |
- 一闪即逝的美:lambda函数适合简单的操作,它们无需定义即可使用,非常适合用在高阶函数中。
13. map()函数:批量操作的艺术
1
| def square(n):<br> return n*n<br><br>numbers = [1, 2, 3, 4]<br>squared_numbers = list(map(square, numbers))<br>print(squared_numbers) <em># 输出: [1, 4, 9, 16]</em><br><br><em># 或者用lambda简化</em><br>simplified = list(map(lambda x: x*x, numbers))<br>print(simplified) <em># 同上</em> |
- 批量处理好帮手:map函数对序列的每个元素应用指定函数,返回一个迭代器对象,通常转换为列表使用。
14. filter()函数:筛选高手
1
| def is_even(n):<br> return n % 2 == 0<br><br>numbers = [1, 2, 3, 4, 5, 6]<br>even_numbers = list(filter(is_even, numbers))<br>print(even_numbers) <em># 输出: [2, 4, 6]</em><br><br><em># 简化版</em><br>even_with_lambda = list(filter(lambda x: x % 2 == 0, numbers))<br>print(even_with_lambda) <em># 同上</em> |
- 只选对的:filter函数根据提供的函数来筛选序列中的元素,返回一个迭代器,同样常用list转换。
15. reduce()函数:累积计算的秘密武器
1
| from functools import reduce<br><br>def accumulator(acc, item):<br> return acc + item<br><br>numbers = [1, 2, 3, 4]<br>sum_of_numbers = reduce(accumulator, numbers, 0)<br>print(sum_of_numbers) <em># 输出: 10</em><br><br><em># 或用lambda简化</em><br>sum_with_lambda = reduce(lambda acc, item: acc + item, numbers, 0)<br>print(sum_with_lambda) <em># 同上</em> |
- 累积力量:reduce将一个函数应用于序列的所有元素,累积结果,非常适合求和、乘积等操作。
16. 偏函数partial:定制化的便捷
1
| from functools import partial<br><br>def power(base, exponent):<br> return base ** exponent<br><br>square = partial(power, exponent=2)<br>print(square(5)) <em># 输出: 25</em><br><br>cube = partial(power, exponent=3)<br>print(cube(3)) <em># 输出: 27</em> |
- 定制你的函数:偏函数可以固定原函数的部分参数,生成新的函数,非常适用于需要多次调用且参数变化不大的场景。
17. 递归优化与尾递归
1
| <em># 注意:Python标准解释器不直接支持尾递归优化</em><br>def factorial_tail(n, accumulator=1):<br> if n == 1:<br> return accumulator<br> else:<br> return factorial_tail(n-1, n*accumulator)<br><br>print(factorial_tail(5)) <em># 输出: 120</em> |
- 尾声:虽然Python没有内置的尾递归优化,理解尾递归的概念对理解函数调用栈很有帮助。
18. 闭包进阶:数据封装
1
| def counter_maker():<br> count = 0<br> def increment():<br> nonlocal count<br> count += 1<br> return count<br> return increment<br><br>counter1 = counter_maker()<br>counter2 = counter_maker()<br><br>print(counter1(), counter1()) <em># 输出: 1 2</em><br>print(counter2(), counter2()) <em># 输出: 1 2</em> |
- 工厂模式:闭包可以用来创建具有独立状态的函数,类似于面向对象中的实例。
19. 高阶函数:函数的函数
1
| def apply_operation(func, a, b):<br> return func(a, b)<br><br>add = lambda x, y: x + y<br>subtract = lambda x, y: x - y<br><br>print(apply_operation(add, 5, 3)) <em># 输出: 8</em><br>print(apply_operation(subtract, 5, 3)) <em># 输出: 2</em> |
- 函数的魔力:高阶函数可以接受函数作为参数或返回函数,这是函数式编程的核心概念。
20. 装饰器进阶:带参数的装饰器
1
| def repeat(n):<br> def decorator(func):<br> def wrapper(*args, **kwargs):<br> for _ in range(n):<br> func(*args, **kwargs)<br> return wrapper<br> return decorator<br><br>@repeat(3)<br>def say_hello():<br> print("Hello!")<br><br>say_hello() <em># 输出: Hello! Hello! Hello!</em> |
- 装饰器的新维度:带参数的装饰器让装饰器本身也变得灵活,可以根据需要调整行为。
至此,我们探索了Python函数从基础到进阶的20个最佳实践,每一个点都是打开新视野的钥匙。