04. 函数

目录

1、前言

2、Python中的函数

2.1、内置函数

2.2、自定义函数

2.3、函数调用

3、函数的参数

3.1、形参和实参

3.2、位置参数(Positional Arguments)

3.3、默认参数(Default Arguments):

3.4、关键字参数(Keyword Arguments):

3.5、可变位置参数(Arbitrary Argument Lists):

3.6、可变关键字参数(Arbitrary Keyword Argument Lists):

4、函数高级特性

4.1、匿名函数(Lambda)

4.2、闭包(Closure)

4.3、装饰器(Decorator)

4.4、递归函数

5、小结


1、前言

在Python编程中,函数是一项强大而灵活的工具,它不仅能够使代码更有组织性,还能提高代码的重用性。函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。前面我们已经有接触过一些Python提供的内建函数了,比如print()。我们也可以自己创建函数,这被叫做用户自定义函数。

2、Python中的函数

Python中函数大体上可以分为两类:内置函数、自定义函数。

2.1、内置函数

Python内置了很多函数,我们可以直接调用。如常见的len(),list(),print()等。Python已内置的函数可以通过如下日志查看:https://docs.python.org/3/library/functions.html

2.2、自定义函数

Python中如果想定义一个自己的函数,遵循以下简单的规则:

  • 函数代码块以 def ()
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 

如自定义一个加法运算的函数:

# def为定义函数的关键字
# my_add为该函数的名称,提供给被调用方调用
# a, b为该函数体的参数,也就是形参。调用方可以传入指定类型参数进行传递运算
# a + b为函数体,指该函数具体执行的动作
# return为该函数的返回结果
def my_add(a, b):
    return a + b

所以上述定义的函数具体表现为:定义了一个名为my_add的加法运算函数,接收a和b两个参数,返回a和b的加法运算结果。

2.3、函数调用

要调用一个函数,只需要知道该函数名称和该函数接收的参数类型即可。如调用上述的my_add方法:

调用函数时,如果传入的参数数量不对,会提示TypeError,如:

if __name__ == '__main__':
    print(my_add(3, 4, 5))

这里很明确的指出my_add()方法接收2个参数,但是却给了3个。

如果传输的数量是对的,但是类型无法被接受,也会包TypeError错误,如:

if __name__ == '__main__':
    print(my_add(3, '12'))

因为函数体具体实现用的是+加法运算,程序默认a和b均为int类型。这里传入了'abc'明显是字符串,因此程序出错。要正确使用也很简单,只要做个类型转换即可:

if __name__ == '__main__':
    # 这里将'12'字符串类型通过int()转换为int型
    print(my_add(3, int('12')))

3、函数的参数

定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解。

在Python中,函数的参数是在函数定义中列出的变量,用于接收传递给函数的值。函数参数分为几种不同类型:位置参数,默认参数,关键字参数,可变位置参数,可变关键字参数。

3.1、形参和实参

在编程中,函数参数通常分为两种:形式参数(形参)和实际参数(实参)。

形式参数(形参): 在函数定义中声明的参数称为形式参数。形参是函数定义的一部分,它们是函数内部的变量名,用于接收调用函数时传递的实参的值。形参在函数定义中充当占位符,告诉函数应该接受什么样的输入。

def example_function(parameter1, parameter2):
    # 函数体
    pass

其中,parameter1和parameter2就是形式参数。

实际参数(实参): 在函数调用时提供的具体数值或对象称为实际参数。实参是传递给函数的真实数据,它们与函数定义中的形参一一对应,按照顺序传递或使用关键字参数进行指定。

example_function(value1, value2)

其中,value1和value2就是实际参数。它们被传递给函数 example_function,并分别赋值给函数定义中的 parameter1 和 parameter2。

3.2、位置参数(Positional Arguments)

Python中这是最常见的参数类型,按照位置顺序传递给函数。函数定义时,参数的顺序和数量必须与函数调用时传递的顺序和数量一致。

def example_function(arg1, arg2, arg3):
    # 函数体
    pass

# 调用函数
example_function(value1, value2, value3)

3.3、默认参数(Default Arguments)

在函数定义时,可以为某些参数指定默认值,这样在调用函数时如果不提供相应参数的值,将使用默认值。

def example_function(arg1, arg2, arg3="default_value"):
    # 函数体
    pass

# 调用函数
example_function(value1, value2)

3.4、关键字参数(Keyword Arguments)

在函数调用时,可以通过参数名直接指定传递的值,而不依赖于参数的位置。

def example_function(arg1, arg2, arg3):
    # 函数体
    pass

# 调用函数,使用关键字参数
example_function(arg1=value1, arg3=value3, arg2=value2)

3.5、可变位置参数(Arbitrary Argument Lists)

使用星号*可以让函数接受可变数量的位置参数,这些参数将被封装为一个元组。

def example_function(*args):
    # args是一个包含所有位置参数的元组
    pass

# 调用函数
example_function(value1, value2, value3)

3.6、可变关键字参数(Arbitrary Keyword Argument Lists)

使用双星号**可以让函数接受可变数量的关键字参数,这些参数将被封装为一个字典。

def example_function(**kwargs):
    # kwargs是一个包含所有关键字参数的字典
    pass

# 调用函数
example_function(arg1=value1, arg2=value2, arg3=value3)

函数的参数在调用时需要与函数定义中的参数顺序和类型相匹配,但通过使用默认参数、关键字参数、可变位置参数和可变关键字参数等特性,可以增加函数的灵活性,使其更加适应各种使用场景。

4、函数高级特性

4.1、匿名函数(Lambda)

Lambda函数是一种简洁的函数定义方式,适用于一些简单的操作。下面是一个Lambda函数的示例:

square = lambda x: x ** 2

# 调用Lambda函数
result = square(5)
print(result)  # 输出结果:25

Lambda函数通常用于需要一个简单函数作为参数的情况,比如在map和filter等函数中。

4.2、闭包(Closure)

闭包是指在一个函数内部定义另一个函数,并且内部函数可以访问外部函数的局部变量。以下是一个闭包的例子:

def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

closure = outer_function(10)
result = closure(5)
print(result)  # 输出结果:15

在这个例子中,outer_function返回了一个内部函数inner_function,并且inner_function可以访问外部函数的变量x,形成了一个闭包。

4.3、装饰器(Decorator)

装饰器是一种用于修改函数行为的高级特性,常用于在不改变原函数代码的情况下添加额外功能。以下是一个简单的装饰器示例:

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

# 调用被装饰后的函数
say_hello()

在上述例子中,my_decorator是一个装饰器函数,通过@my_decorator语法应用到say_hello函数上。调用say_hello时,实际上是调用了被装饰后的函数,从而在执行前后添加了额外的功能。

通过深入了解和灵活运用这些函数的基础概念和高级特性,可以更好地编写清晰、模块化和可维护的Python代码。希望本文的示例代码能够帮助读者更好地理解Python函数的使用和应用。

4.4、递归函数

在函数中,我们除了调用别人定义的函数外,也可以调用自身,这就是函数递归。举个例子:

def factorial(n):
    """计算阶乘的递归函数"""
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial(n - 1)

# 调用递归函数
result = factorial(5)
print(result)  # 输出结果:120

上述代码中,factorial 函数用于计算阶乘。递归调用发生在 n * factorial(n - 1) 这一行,函数自身被调用并传递了一个较小的参数 n - 1。递归的结束条件是 n == 0 or n == 1,当 n 等于 0 或 1 时,递归停止,直接返回 1。

递归函数通常包括两个部分:

  1. 基本情况(Base Case):定义递归终止的条件。在上面的例子中,基本情况是 n == 0 or n == 1。
  2. 递归情况(Recursive Case):定义函数如何调用自身,并缩小问题规模。在上述例子中,递归情况是 n * factorial(n - 1)。

需要注意的是,递归函数的性能可能不如迭代(循环)实现,因为递归会涉及到多个函数调用,导致函数栈的不断增长。在某些情况下,可以通过尾递归优化或使用迭代方式来提高性能。

当使用递归时,确保设置好递归结束的条件,以避免无限递归。适当的使用递归可以使代码更加清晰、简洁,但在解决一些问题时,迭代可能是更好的选择。

5、小结

Python中函数的重要性无法被低估,它是代码模块化、重用和可维护性的关键。函数是Python编程中不可或缺的一部分,它们为代码提供了结构、可读性和可维护性,是构建复杂程序的基石。函数的设计和使用是成为Python程序员的重要技能之一。

猜你喜欢

转载自blog.csdn.net/p793049488/article/details/134764581