- 自己创建的函数被称为用户自定义函数。
- Python通过使用def关键字来定义函数。
- Python函数可以有输入参数,这些参数在函数被调用时传递给函数。
- Python函数可以有一个返回值,这个值可以是任何Python支持的数据类型。函数通过return语句返回值。
- 函数调用:定义了函数之后,你可以通过函数名和传递相应的参数来调用它。
# 一个简单的函数定义,名为greet,接受一个参数name
def greet(name):
print("Hello, " + name)
# 调用函数
greet("Alice") # 输出: Hello, Alice
# 这个函数接受两个参数并返回它们的和
def add(a, b):
return a + b
# 调用函数
result = add(1, 2)
print(result) # 输出: 3
# 这个函数接受任意数量的参数,并返回它们的最大值
def max(*args):
return max(args)
# 调用函数
print(max(1, 2, 3, 4, 5)) # 输出: 5
- 在Python中,函数调用时参数传递方式是一种“传对象引用”的方式。
- 在函数中传递一个变量时,实际上传递的是该变量所引用的对象的引用,而不是变量的值本身。
- 当函数被调用时,Python会为每个参数创建一个新的局部变量,并将这些局部变量与传入的实际参数关联起来。
- 如果实际参数是一个不可变类型(如整数、字符串或元组),那么在函数内部对该参数的任何修改都不会影响到函数外部的原始变量。这是因为不可变类型的值是不能改变的,所以任何对参数的修改都会创建一个新的对象。
- 如果实际参数是一个可变类型(如列表或字典),那么在函数内部对该参数的修改可能会影响到函数外部的原始变量。这是因为可变类型的值可以改变,所以对参数的修改实际上是在修改原始对象。
- 用于高阶函数时,Python允许将函数作为参数传递给其他函数。这种情况下,传递的是函数对象的引用,而不是函数的执行结果。
命 名 | 函数的命名应该具有可读性,能够清晰地表达函数的功能或作用。这有助于代码的维护和理解。 |
参数传递 | 在调用函数时,需要注意参数的类型和数量是否与函数定义匹配。传递的参数会按位置顺序赋值给函数定义中的形参。 |
模块化 | 函数可以提高应用的模块性,使得代码更加结构化,便于管理和复用,当程序出现问题时,良好的函数划分可以帮助快速定位问题所在,因为每个函数负责单一的功能模块。 |
缺省参数 | 在定义函数时,可以为参数设置缺省值,这样在调用函数时如果不提供该参数的值,就会使用缺省值。但是要注意,缺省参数的使用可能会引起意想不到的副作用,特别是在可变数据类型作为缺省参数时。 |
缩进规则 | Python中缩进是用来区分代码块的,因此函数体内的代码需要有统一的缩进,通常使用四个空格来缩进。 |
- 递归:将复杂的问题逐步分解,直到达到一个足够简单的基本情况,也就是递归基,然后从那里开始逐步返回解决结果。
- 递归基:递归终止的条件,当满足这些条件时,函数不再调用自身,而是返回一个特定值。
- 递归表达式:函数如何将问题分解为更小的子问题,并在每次调用时传递缩小的问题规模。
- 在实现递归时,需要注意以下几点:
- 确保有递归基:每个递归函数都必须有一个递归基,否则函数将无限制地调用自身,导致程序崩溃。
- 递归深度:Python默认的递归深度限制是1000,超过这个深度会导致RecursionError。如果需要更深的递归,可以使用sys模块的setrecursionlimit()函数来增加限制。
- 效率问题:递归虽然代码简洁,但并不是所有问题都适合用递归解决,因为递归可能会导致大量的函数调用,消耗更多的内存和CPU资源。
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
print(factorial(5)) # 输出 120
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 输出 55
此例中,fibonacci()函数接受一个整数参数n,并返回斐波那契数列中的第n项。如果n等于0或1,则直接返回对应的值。否则,函数将调用自身两次,分别计算F(n-1)和F(n-2)的值,并将它们相加得到结果。函数逐步缩小问题规模,直到达到基本情况(即n为0或1),然后开始逐步返回结果。