Appearance
🛠 函数
Python 中的函数是组织好的、可重复使用的代码块,用来执行某个特定的任务。使用函数可以提高代码的复用性,减少重复的代码,并增强程序的可读性和可维护性。
函数在编程中的主要优点包括:
- 代码组织和模块化:把复杂任务拆分成小的、独立的函数,提升代码的结构性。
- 复用性:通过函数的复用,避免代码重复,提高效率。
- 可读性:函数有助于让代码更具可读性,帮助开发者理解程序的功能。
- 可维护性:修改和扩展程序时,只需修改函数内部的实现,不会影响到其他部分。
- 易于测试:函数可以独立地进行单元测试,确保功能的正确性。
- 灵活性和扩展性:通过参数化,函数可以处理不同的输入,增强灵活性。
通过合理使用函数,可以让程序更简洁、清晰、可复用,从而提升开发效率和代码质量。
一、定义函数
在 Python 中,函数是通过 def 关键字来定义的:
python
def function_name(parameters):
statement # 语句
return result # 语句:返回结果function_name是函数的名字。parameters是函数的参数,可以有多个,参数是可选的。statement是函数内部的代码部分,它包含了函数执行时要完成的具体操作或任务。函数体由一系列语句组成,负责实现函数的功能。return语句是可选的,用于返回函数的结果。如果没有return,函数默认返回None。 示例:
python
def greet(name):
s = f"Hello, {name}!"
return s这个函数 greet 接收一个参数 name,返回一个格式化的字符串。
二、调用函数
函数定义完成后,可以通过函数名来调用它,给它传递所需的参数。
python
message = greet("Alice")
print(message)输出:
Hello, Alice!三、参数
在 Python 中,函数的参数可以有多种不同的形式,包括位置参数、关键字参数、可变参数等。理解这些参数的不同类型和它们的顺序对于编写清晰、灵活的函数非常重要。
1. 位置参数(Positional Arguments)
位置参数是最常见的参数类型,它们是通过传入的值按照定义时的顺序传递给函数的。 示例:
python
def greet(name, age):
print(f"Hello {name}, you are {age} years old.")
greet("Alice", 30) # 输出 Hello Alice, you are 30 years old.在这个例子中,name 和 age 是位置参数。传入的 "Alice" 和 30 会按照顺序赋给 name 和 age。
2. 关键字参数(Keyword Arguments)
关键字参数是通过指定参数名来传递值,而不依赖于参数的位置。它们通常在调用函数时明确指定每个参数的名字。
python
def greet(name, age):
print(f"Hello {name}, you are {age} years old.")
greet(age=30, name="Alice") # 输出 Hello Alice, you are 30 years old.在这个例子中,age=30 和 name="Alice" 是关键字参数。它们不受顺序的限制,虽然函数定义是 name, age,但可以通过指定名字来传递参数。
3. 默认参数(Default Arguments)
你可以为函数的参数指定默认值。如果调用函数时没有提供某个参数的值,Python 会使用该参数的默认值。
python
def greet(name, age=25):
print(f"Hello {name}, you are {age} years old.")
greet("Alice") # 输出 Hello Alice, you are 25 years old.
greet("Bob", 30) # 输出 Hello Bob, you are 30 years old.在这个例子中,age 有一个默认值 25。如果没有传入 age,Python 会使用默认值。
4. 可变参数(Variable-Length Arguments)
*args(位置参数-元组)
*args 用于接受任意数量的位置参数。它将所有传入的位置参数收集到一个元组中。
python
def greet(*args):
for arg in args:
print(f"Hello {arg}")
greet("Alice", "Bob", "Charlie")
# 输出:
# Hello Alice
# Hello Bob
# Hello Charlie在这个例子中,*args 收集了所有传入的参数,并将它们作为元组来处理。
**kwargs(关键字参数-字典)
**kwargs 用于接受任意数量的关键字参数。它将所有传入的关键字参数收集到一个字典中。
python
def greet(**kwargs):
for name, age in kwargs.items():
print(f"Hello {name}, you are {age} years old.")
greet(Alice=30, Bob=25, Charlie=35)
# 输出:
# Hello Alice, you are 30 years old.
# Hello Bob, you are 25 years old.
# Hello Charlie, you are 35 years old.在这个例子中,**kwargs 收集了所有传入的关键字参数,并将它们作为字典来处理。
*args:就像你传给函数一个元组,其中包含了所有的位置参数,按顺序排列。
**kwargs:就像你传给函数一个字典,字典的键是参数名,值是参数值。
5. 参数顺序
在函数定义时,参数的顺序非常重要。以下是参数的顺序规则:
- 位置参数:这些参数必须先于关键字参数和可变参数。
- 默认参数:默认参数必须放在位置参数之后。
*args:*args位于其他所有位置参数之后,否则后面的参数只能通过关键字传参。**kwargs:**kwargs必须位于*args后面,并且它通常是最后一个参数。
python
def func(a, b, c=3, *args,**kwargs):
print(a, b, c, args,kwargs)
func(1, 2, 3, 5, 6, 7,name="Alice", age=25)a, b是位置参数。c=3是带默认值的参数。*args是接受多个位置参数的元组。**kwargs是接受多个关键字参数的字典。
6. 参数的注意事项
- 不能重复定义参数名:在同一个函数定义中,不能同时有位置参数和关键字参数的同名参数。
*args和**kwargs:*args用于捕获额外的位置参数,而**kwargs用于捕获额外的关键字参数。它们通常放在最后,且只能有一个*args和一个**kwargs。
7. 总结
- 位置参数:传递给函数时按照定义的顺序进行匹配。
- 关键字参数:通过明确指定参数名来传递,可以不依赖顺序。
- 默认参数:可以在函数定义时为某些参数提供默认值。
*args:接受任意数量的位置参数并将它们作为元组传递。**kwargs:接受任意数量的关键字参数并将它们作为字典传递。 函数的参数机制非常灵活,能够满足各种不同的需求。在编写函数时,理解这些参数的使用顺序和规则,可以让代码更加简洁、可读且高效。
四、变量的作用域
- 局部作用域:在函数内部定义的变量,只能在函数内部使用。
- 全局作用域:在函数外部定义的变量,可以在函数内外使用(如果在函数内没有局部变量与之同名)。
python
x = 10 # 全局变量
def my_func():
x = 5 # 局部变量
print(f"Inside function: {x}")
my_func() # 输出 Inside function: 5
print(f"Outside function: {x}") # 输出 Outside function: 10如果需要在函数内部修改全局变量,需要使用 global 声明:
python
x = 10 # 全局变量
def my_func():
global x # 声明要使用全局变量 x
x = 5 # 修改全局变量
print(f"Inside function: {x}")
my_func() # 输出 Inside function: 5
print(f"Outside function: {x}") # 输出 Outside function: 5如果需要在函数内部修改上一层的变量,需要使用 nonlocal 声明:
python
def outer():
x = 0
def inner():
nonlocal x
x = x + 1
print(x)
inner()
inner()
outer()程序输出:
1
2
Python 查找变量的规则是LEGB:
| 层级 | 名称 | 范围 / 例子 |
|---|---|---|
| L – Local(局部作用域) | 当前函数内部 | 函数内部定义的变量、参数 |
| E – Enclosing(封闭作用域) | 外层函数(闭包) | 如果函数嵌套,上一层函数的变量 |
| G – Global(全局作用域) | 模块级别 | 当前模块中定义的变量 |
| B – Built-in(内建作用域) | Python 内建 | len(), print(), int 等 |
五、Lambda 函数
Lambda 函数是 Python 中的一种匿名函数,通常用于简化代码,尤其是当函数体非常简单时。它允许你在一行代码中定义一个小的函数,而不需要使用 def 来命名函数。语法如下:
python
lambda arguments: expressionlambda 关键字表示定义一个匿名函数。
参数:类似于普通函数的参数,可以是一个或多个。
表达式:该表达式会被计算并返回,它的值是 Lambda 函数的返回值。
示例:
python
square = lambda x: x ** 2
print(square(4)) # 输出 16Lambda 函数通常用于那些短小、简单的函数场景。它只能包含一个表达式。所以它功能有限,仅适合处理简单的逻辑,不适合复杂的多语句操作。
六、递归函数
函数可以调用自身,这种函数称为递归函数。递归函数通常有一个终止条件,避免无限循环。
python
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 输出 120七、空函数
空函数(也叫占位符函数)是指没有任何实际功能的函数,通常用于结构性设计中,作为占位符或者接口定义,目的是后续填充具体的实现。空函数在程序开发初期、调试阶段或者需要接口定义时非常有用。
在 Python 中,空函数的定义非常简单,通常是通过 pass 语句来实现的。pass 语句是一个空操作,什么都不做,只是占据了语法的位置。
python
def empty_function():
pass # 空函数体,什么都不做在上面的例子中,empty_function 是一个空函数,它没有任何实际操作,调用这个函数时不会执行任何任务。
八、高阶函数
高阶函数(Higher-Order Functions)是指可以接受其他函数作为参数,或者返回一个函数作为结果的函数。它是函数式编程的一个核心概念,广泛应用于许多编程语言中,包括 Python。
高阶函数有以下两个关键特点:
- 接收函数作为参数:高阶函数可以接受其他函数作为参数,允许我们在调用时传递行为。
- 返回一个函数:高阶函数可以返回一个新的函数,使得函数的行为可以动态改变。
九、文档字符串
在 Python 中,文档字符串是一个放在函数体内部第一行的字符串,通常用于解释函数的功能、参数和返回值等信息。文档字符串可以用 help() 来查看。
python
def greet(name):
"""
Greets the user with a message.
Parameters:
name (str): The name of the user to greet.
Returns:
str: A greeting message.
"""
return f"Hello, {name}!"
help(greet)输出:
python
Help on function greet in module __main__:
greet(name)
Greets the user with a message.
Parameters:
name (str): The name of the user to greet.
Returns:
str: A greeting message.- 功能说明:简洁地描述函数做了什么。
- 参数:列出所有参数的名字和类型,描述它们的作用。
- 返回值:描述函数的返回值类型和内容。
十、内嵌函数
Python 函数内部可以定义函数,这种做法被称为嵌套函数。嵌套函数是指在一个函数内部定义另一个函数。
python
def outer_function(x):
def inner_function(y):
return y + 1
result = inner_function(x) # 调用内部函数
return result
print(outer_function(5)) # 输出 6十一、练习题
- 定义一个空函数
do_nothing(),该函数不接受任何参数,也不返回任何内容。 - 定义一个函数
greet(),该函数打印Hello, world!。 - 定义一个函数
add_numbers(a, b),接受两个参数a和b,返回它们的和。 - 定义一个函数
multiply_numbers(a, b),接受两个参数a和b,返回它们的乘积。 - 定义一个函数
draw_square(side_length),让海龟画一个正方形,边长由side_length决定。 - 定义一个函数
calculate_area(radius),计算并返回圆的面积。该函数接收一个参数radius,表示圆的半径,返回圆的面积。 - 定义一个函数
is_even(n),判断一个数字n是否为偶数。如果是偶数返回True,否则返回False。 - 定义一个函数
greet_person(name, age),该函数打印一条问候信息:Hello {name}, you are {age} years old. - 定义一个函数
sum_numbers(*numbers),接收任意数量的数字作为位置参数,并返回这些数字的和。 - 定义一个函数
print_person_info(**info),接受一个字典类型的参数,打印出所有键值对。 - 定义一个函数
draw_circle(radius),让海龟画一个圆,半径由radius决定。 - 定义一个函数
draw_shapes(*shapes),接收多个形状,支持circle和square,并根据传入的大小绘制相应的图形。 - 定义一个函数
get_position(x, y),该函数返回一个元组(x, y),表示坐标。调用此函数并打印返回的坐标。 - 定义一个函数
max_of_three(a, b, c),接受三个参数并返回它们中的最大值。 - 定义一个函数
get_name_and_age(),返回一个元组(name, age)。调用该函数并打印返回的值。 - 定义一个函数
count_vowels(text),统计文本中元音字母的数量,并返回该数量。 - 定义一个函数
draw_multiple_shapes(),它能够绘制多个形状,传入不同的形状(如circle和square)和大小。每个形状可以传递颜色作为关键字参数。 - 定义一个函数
is_prime(n),判断一个数n是否是质数,如果是返回True,否则返回False。 - 定义一个函数
update_person_info(info),接受一个字典参数info,更新其中的age为35,并返回更新后的字典。 - 定义一个函数
convert_to_dict(*args),将传入的任意数量的参数转换为字典,其中每个参数作为键,值为None。返回该字典。 - 定义一个递归函数
factorial(n),计算并返回整数n的阶乘。即n! = n * (n-1) * (n-2) * ... * 1。 - 定义一个递归函数
fibonacci(n),返回斐波那契数列的第n项。斐波那契数列的定义是:f(0) = 0,f(1) = 1,其他项为前两项之和,即f(n) = f(n-1) + f(n-2)。 - 定义一个递归函数
sum_of_digits(n),计算并返回数字n中各个数字的和。例如,输入123应返回1 + 2 + 3 = 6。 - 定义一个递归函数
reverse_string(s),返回字符串s的反转。例如,输入hello应返回olleh。 - 定义一个递归函数
power(base, exp),计算并返回base的exp次方。即base**exp。