文章目录
- 为什么要使用函数?
- 函数的定义 (`def`)
- 函数的调用
- 函数参数 (Parameters vs Arguments)
- 返回值 (`return`)
- 变量作用域 (简要了解)
- 总结
- 练习题
- 练习题答案
- **创作不易,请大家点赞加收藏,关注我,持续更新教程!**
到目前为止,我们已经学习了基本的数据类型、集合类型以及控制程序流程的条件语句和循环。随着程序越来越复杂,我们可能会发现自己反复编写相同的代码块来执行特定任务。这不仅低效,还会导致代码难以阅读和维护。
函数就是解决这个问题的重要工具。它们允许我们将一段代码封装起来,赋予一个名字,然后在需要的时候多次调用。本篇博客将深入讲解如何定义自己的函数、如何调用它们,以及如何使用 return
语句从函数中获取结果。
为什么要使用函数?
使用函数的好处多多:
- 代码重用 (Reusability): 避免重复编写相同的代码块。遵循 DRY (Don’t Repeat Yourself) 原则。
- 模块化 (Modularity): 将程序分解成更小、更易于管理和理解的部分。每个函数负责一个特定的任务。
- 提高可读性 (Readability): 通过有意义的函数名,代码变得更容易理解其目的。
- 易于维护和调试 (Maintainability & Debugging): 当需要修改或修复某个功能的代码时,只需在一个地方(函数定义处)进行修改。如果出现错误,更容易定位问题在哪个函数中。
函数的定义 (def
)
在 Python 中,使用 def
关键字来定义一个函数。定义函数的基本结构如下:
def function_name(parameter1, parameter2, ...):"""这里是函数的文档字符串 (Docstring)。解释函数的功能、参数和返回值。"""# 函数体 - 执行任务的代码块# ...# return value # 可选的返回值
def
关键字: 标记着一个函数的定义开始。function_name
: 函数的名字。需要遵循 Python 的命名规则(通常使用小写字母和下划线_
组合,称为 snake_case)。函数名应该能够清晰地表明函数的功能。- 圆括号
()
: 紧跟在函数名后面。里面可以包含参数 (Parameters),用于接收外部传递进来的数据。如果没有参数,圆括号也不能省略。 - 冒号
:
: 标记着函数头部的结束,函数体即将开始。 - 文档字符串 (Docstring): 使用三引号
""" """
或''' '''
包围起来的一段文本。它应该在函数头部的下一行,用于详细说明函数的作用。这是 Python 的一个重要特性,可以通过help(function_name)
或function_name.__doc__
查看。编写良好的文档字符串是好习惯。 - 函数体: 缩进的代码块,包含了函数执行的实际操作。
return
语句: 用于指定函数执行完毕后返回给调用者的值。是可选的。
示例: 定义一个简单的函数,它不接受参数,也不返回值,只打印一条消息。
def greet():"""这是一个简单的打招呼函数。"""print("Hello, welcome to Python functions!")print("This function does not take arguments and does not return a value.")
上面的代码只是定义了一个函数,它还没有被执行。
函数的调用
定义函数后,要让它执行里面的代码,就需要调用它。调用函数非常简单,只需要使用函数名后面加上圆括号 ()
即可。如果函数定义时有参数,调用时需要在圆括号中提供相应的实参 (Arguments)。
# 调用上面定义的 greet 函数
greet()
greet() # 函数可以被多次调用
输出:
Hello, welcome to Python functions!
This function does not take arguments and does not return a value.
Hello, welcome to Python functions!
This function does not take arguments and does not return a value.
函数参数 (Parameters vs Arguments)
- 参数 (Parameters): 在函数定义时,圆括号中列出的变量名。它们是函数内部使用的占位符,代表函数期望接收的数据。
- 实参 (Arguments): 在函数调用时,传递给函数参数的实际值。
# 定义一个接受一个参数的函数
def greet_person(name):"""向指定名字的人打招呼。Args:name: 要打招呼的人的名字 (字符串)。"""print(f"Hello, {name}!")# 调用函数,并传递实参
greet_person("Alice") # "Alice" 是传递给 name 参数的实参
greet_person("Bob") # "Bob" 是传递给 name 参数的实参
输出:
Hello, Alice!
Hello, Bob!
一个函数可以有多个参数,调用时需要按照参数定义的顺序传递实参。
# 定义一个接受两个参数的函数
def add_numbers(a, b):"""计算两个数字的和。Args:a: 第一个数字。b: 第二个数字。"""sum_result = a + bprint(f"{a} + {b} = {sum_result}")# 调用函数,传递两个实参
add_numbers(5, 3) # a=5, b=3
add_numbers(10, 20) # a=10, b=20
输出:
5 + 3 = 8
10 + 20 = 30
调用带有参数的函数时,必须提供正确数量的实参(对于目前我们学习的必需参数)。
返回值 (return
)
函数的一个重要作用是执行计算并将结果返回给调用者。使用 return
语句来实现。
return value
: 函数执行到return
语句时,会立即停止执行,并将value
返回给调用者。- 如果函数没有
return
语句,或者只有不带值的return
,它会隐式地返回特殊的值None
。 None
是 Python 中表示“无”或“空”的一个特殊对象。
# 定义一个函数,使用 return 返回计算结果
def multiply(x, y):"""计算两个数字的乘积并返回结果。Args:x: 第一个数字。y: 第二个数字。Returns:两个数字的乘积。"""product = x * yreturn product # 返回计算得到的乘积# 调用函数,并用变量接收返回值
result = multiply(4, 6)
print(f"乘积是: {result}") # 输出: 乘积是: 24another_result = multiply(2.5, 4)
print(f"另一个乘积是: {another_result}") # 输出: 另一个乘积是: 10.0
注意: return
语句一旦执行,函数就会结束。return
后面的代码将不会被执行。
def example_return(num):if num > 10:return "大于 10" # 如果 num > 10,函数在这里结束print("数字不大于 10") # 如果 num <= 10,这行会执行return "小于或等于 10" # 然后返回这个值print(example_return(15)) # 输出: 大于 10
print(example_return(8)) # 输出: 数字不大于 10\n小于或等于 10
隐式返回 None
:
def print_message(msg):"""只打印消息,没有 return 语句。"""print(msg)# 隐式地返回 Nonereturn_value = print_message("Hello")
print(f"函数返回的值是: {return_value}") # 输出: Hello\n函数返回的值是: None
返回多个值:
Python 函数可以看似返回多个值,实际上,它是将多个值封装在一个元组 (tuple) 中返回。
def get_name_and_age():"""返回名字和年龄。"""name = "Charlie"age = 25return name, age # 实际上返回 ('Charlie', 25)info = get_name_and_age()
print(f"获取到的信息是: {info}") # 输出: 获取到的信息是: ('Charlie', 25)
print(f"类型是: {type(info)}") # 输出: 类型是: <class 'tuple'># 可以使用元组解包来分别获取返回值
person_name, person_age = get_name_and_age()
print(f"名字: {person_name}, 年龄: {person_age}") # 输出: 名字: Charlie, 年龄: 25
变量作用域 (简要了解)
在函数内部定义的变量(包括参数)通常是局部变量 (Local Variables)。它们只存在于函数执行期间,函数结束后就会被销毁,在函数外部无法访问。
def my_function():x = 10 # x 是局部变量print(f"函数内部的 x: {x}")my_function()
# print(x) # 这会引发 NameError,因为 x 在函数外部不存在
全局变量(在函数外部定义的变量)可以在函数内部访问,但不建议在函数内部直接修改全局变量,除非使用 global
关键字(但这通常是初学者应尽量避免的高级用法)。将数据通过参数传递进函数,通过返回值传出,是更好的实践。
总结
函数是 Python 中组织代码、实现重用和模块化的核心工具。本篇我们学习了:
- 使用
def
关键字定义函数。 - 理解参数 (Parameters) 和实参 (Arguments) 的区别。
- 如何调用函数来执行其代码。
- 使用
return
语句从函数中返回一个或多个值。 - 函数没有显式返回值时默认返回
None
。 - 函数内部变量的局部作用域概念。
- 编写文档字符串说明函数功能。
练习题
尝试独立完成以下练习题,并通过答案进行对照:
-
简单函数定义与调用:
- 定义一个函数
print_hello()
,它不接受参数,只打印 “Hello, Python!”。调用这个函数。
- 定义一个函数
-
带参数的函数:
- 定义一个函数
say_greeting(name)
,它接受一个字符串参数name
,并打印 “Hello, [name]!”。调用这个函数,传入你的名字。
- 定义一个函数
-
带返回值的函数:
- 定义一个函数
calculate_square(number)
,它接受一个数字参数number
,计算并返回这个数字的平方。调用这个函数,并打印返回值。 - 定义一个函数
is_even(number)
,它接受一个整数参数number
,如果数字是偶数返回True
,否则返回False
。调用这个函数测试几个数字。
- 定义一个函数
-
返回多个值的函数:
- 定义一个函数
divide_and_remainder(a, b)
,它接受两个数字a
和b
,计算a
除以b
的商和余数,并同时返回这两个结果(作为一个元组)。调用这个函数,并使用元组解包分别获取商和余数,然后打印。
- 定义一个函数
-
结合循环和条件的函数:
- 定义一个函数
count_vowels(text)
,它接受一个字符串参数text
,遍历字符串,统计其中元音字母(a, e, i, o, u,不区分大小写)的数量,并返回数量。调用这个函数测试一些字符串。
- 定义一个函数
-
带文档字符串的函数:
- 为你前面定义的任何一个函数添加一个清晰的文档字符串,说明其功能、参数和返回值。然后使用
help()
函数查看你写的文档。
- 为你前面定义的任何一个函数添加一个清晰的文档字符串,说明其功能、参数和返回值。然后使用
练习题答案
1. 简单函数定义与调用:
# 1. 简单函数定义与调用
def print_hello():"""打印一条简单的问候信息。"""print("Hello, Python!")# 调用函数
print_hello()
2. 带参数的函数:
# 2. 带参数的函数
def say_greeting(name):"""向指定名字的人打招呼。Args:name: 要打招呼的人的名字 (字符串)。"""print(f"Hello, {name}!")# 调用函数
say_greeting("Alice")
say_greeting("Bob")
3. 带返回值的函数:
# 3.1 计算平方并返回
def calculate_square(number):"""计算并返回一个数字的平方。Args:number: 需要计算平方的数字。Returns:number 的平方。"""return number ** 2# 调用并打印返回值
result1 = calculate_square(5)
print(f"5 的平方是: {result1}")result2 = calculate_square(3.5)
print(f"3.5 的平方是: {result2}")# 3.2 判断奇偶数并返回布尔值
def is_even(number):"""判断一个整数是否是偶数。Args:number: 需要判断的整数。Returns:如果数字是偶数返回 True,否则返回 False。"""return number % 2 == 0# 调用并测试
print(f"4 是偶数吗? {is_even(4)}")
print(f"7 是偶数吗? {is_even(7)}")
print(f"0 是偶数吗? {is_even(0)}")
4. 返回多个值的函数:
# 4. 返回多个值的函数
def divide_and_remainder(a, b):"""计算两个数字的商和余数。Args:a: 被除数。b: 除数 (不能为 0)。Returns:一个包含商和余数的元组 (quotient, remainder)。如果 b 为 0,返回 None。"""if b == 0:print("错误: 除数不能为零。")return None # 或者根据需要处理错误quotient = a // b # 整数除法获取商remainder = a % b # 获取余数return quotient, remainder # 返回一个元组# 调用并解包返回值
result_tuple = divide_and_remainder(10, 3)if result_tuple is not None: # 检查返回值是否为 Nonequotient, remainder = result_tuple # 元组解包print(f"10 除以 3 的商是: {quotient}, 余数是: {remainder}")divide_and_remainder(5, 0) # 测试除数为零的情况
5. 结合循环和条件的函数:
# 5. 结合循环和条件的函数
def count_vowels(text):"""统计字符串中元音字母的数量。Args:text: 输入的字符串。Returns:字符串中元音字母 (a, e, i, o, u, 不区分大小写) 的数量。"""vowels = "aeiouAEIOU" # 元音字母集合vowel_count = 0for char in text: # 遍历字符串中的每个字符if char in vowels: # 检查字符是否在元音字母集合中vowel_count += 1return vowel_count# 调用并测试
sentence1 = "Hello World"
count1 = count_vowels(sentence1)
print(f"'{sentence1}' 中的元音字母数量: {count1}")sentence2 = "Python Programming"
count2 = count_vowels(sentence2)
print(f"'{sentence2}' 中的元音字母数量: {count2}")
6. 带文档字符串的函数:
选择上面任意一个函数,确保你已经添加了文档字符串,然后运行以下代码:
# 假设你已经为 calculate_square 函数添加了文档字符串
# 运行以下代码查看文档
help(calculate_square)# 或者直接访问 __doc__ 属性
print("\n--- 通过 __doc__ 属性访问文档字符串 ---")
print(calculate_square.__doc__)
运行 help(calculate_square)
应该会输出你为 calculate_square
函数编写的文档字符串内容(通常会格式化得更漂亮)。