赶紧学函数,不然我就“嘿嘿嘿”了(Python中的函数)

发布时间:2024年01月23日

1.函数的作用

1.1代码复用

使用函数可以将一段常用的代码逻辑封装起来,并在需要时多次调用,避免重复编写相同的代码。

1.2模块化编程

函数帮助将程序分解为更小的模块,每个模块负责完成特定的任务。这样,整个程序就可以更容易理解和管理。

1.3提高代码可读性

通过将代码逻辑封装在函数中,可以提高代码的可读性。函数名和参数的使用可以使得代码更加清晰和易于理解。

1.4参数传递

函数可以接受输入参数,在函数内部对参数进行处理,并返回结果。这样可以方便地将数据传递给函数,并获取函数的返回值。

1.5抽象和封装

函数可以隐藏实现细节,只提供一个接口供外部调用。这样,函数的使用者只需关注函数的功能,而不必关心内部实现细节。

2.函数的构成

函数的定义通常使用def关键字,后跟函数名、参数列表和冒号。函数体位于缩进块中,根据需要执行一些操作,并通过return语句返回结果(如果需要)。
以下是一个简单的Python函数的示例:

def greet(name):
    """打招呼的函数"""
    print("Hello, " + name + "!")

# 调用函数
greet("Alice")  # 输出: Hello, Alice!

我们定义了一个名为greet的函数,它接受一个参数name。函数体中的print语句用于打印一条问候消息。然后,我们通过调用greet函数并传递参数"Alice"来执行该函数。

2.1 函数名的详细说明

函数名是用于唯一标识函数的名称,它应该具有描述性,符合命名规则,避免与其他代码发生冲突,并遵循适当的命名约定和风格指南。

2.1.1命名规则

函数名可以由字母、数字和下划线组成。
函数名必须以字母或下划线开头,不能以数字开头。
函数名不能包含空格或特殊字符(如@、$、%等)。
函数名应该具有描述性,能够清晰地表达函数的功能或目的。
通常使用小写字母和下划线来命名函数,例如calculate_average。

2.1.2 命名约定

Python社区通常遵循一些命名约定,以提高代码的可读性。例如,使用小写字母和下划线来命名函数,以便更容易阅读和理解函数名。
对于内部使用的函数,可以在函数名前面加上一个下划线,表示该函数是供内部使用的。例如,_helper_function。

2.1.3冲突避免

避免使用与Python内置函数或模块名称相同的函数名,以免发生冲突。
也要避免与你自己的代码中已经定义的其他变量、函数或类的名称相同,以免引起混淆。

2.1.4规范和风格指南

Python有一些编码规范和风格指南,例如PEP 8,它提供了关于函数命名的建议。可以遵循这些规范来保持代码的一致性和可读性。
下面是一个示例函数及其函数名的解释

def calculate_average(numbers):
    """计算列表中数字的平均值"""
    total = sum(numbers)
    average = total / len(numbers)
    return average

函数名是calculate_average。它是一个描述性的名称,用于表示函数的功能,即计算给定数字列表的平均值。

2.2 形参

函数的形参是指在定义函数时,用于接收传递给函数的值的占位符参数。形参是函数定义的一部分,它们用于指定函数所需的输入,并将其传递到函数体内:简而言之,就是小括号里面的参数,使用该参数到函数里面运算;

2.2.1形参的定义

在函数定义中,形参是在函数名称后面的括号中定义的。
形参的名称可以是任何有效的Python标识符,例如x、y等。
函数可以有零个或多个形参,用逗号分隔。

2.2.2形参的类型

在Python中,函数的形参不需要指定类型。函数可以接受任何数据类型的参数。
但是,函数可以在使用形参之前对其进行类型检查和转换。

2.2.3 形参的默认值

在定义函数时,可以为形参设置默认值。这样,在调用函数时,如果没有提供该形参的值,则将使用默认值。
定义具有默认值的形参时,应将其放在所有未设置默认值的形参之后

2.2.4 可变数量的形参

在Python中,函数可以接受可变数量的参数。这些参数被称为可变数量的形参。
可变数量的形参可以接受任意数量的位置或关键字参数,并将它们放入一个元组或字典中。

下面是一个示例函数及其形参的解释:

def greet(name, greeting="Hello"):
    """向指定的人打招呼"""
    print(greeting, name)

# 调用函数,传递位置参数和关键字参数
greet("Alice")
greet("Bob", "Hi there!")
greet(greeting="Bonjour", name="Claire")

我们定义了一个名为greet的函数,它接受一个位置参数name和一个具有默认值的关键字参数greeting。如果调用函数时没有提供greeting参数的值,则将使用默认值"Hello"。然后,我们通过调用greet函数并传递不同的位置和关键字参数来执行函数。

2.2.5 形参的总结

总之,函数的形参是用于接收传递给函数的值的占位符参数。形参可以设置默认值,并支持可变数量的形参。形参不需要指定类型,但在使用前可以进行类型检查和转换。

2.3. 实参

函数的实参是指在调用函数时,传递给函数的具体值或变量。实参是函数调用的一部分,它们提供了函数所需的实际输入。

2.3.1 位置参数

当函数定义中的形参按照顺序进行定义时,可以通过位置来传递实参。
例如,如果函数定义为def add(x, y),则可以通过按位置传递实参来调用函数,例如add(2, 3)。

2.3.2 关键字参数

使用关键字参数可以根据形参的名称来传递实参,而不考虑它们在函数定义中的顺序。
关键字参数使用形式为形参名=实参值的语法。
例如,如果函数定义为def greet(name, age),则可以通过关键字参数来调用函数,例如greet(age=25, name=“Alice”)。

2.3.3 混合使用

在函数调用中,可以同时使用位置参数和关键字参数。
当使用混合参数时,位置参数必须在关键字参数之前传递

2.3.4可变数量的实参

在Python中,可以使用星号(*)表示可变数量的位置参数,使用两个星号(**)表示可变数量的关键字参数。
可变数量的位置参数会将实参收集到一个元组中,而可变数量的关键字参数会将实参收集到一个字典中

def add(x, y):
    """计算两个数的和"""
    result = x + y
    print("结果:", result)

# 调用函数,传递位置参数和关键字参数
add(2, 3)
add(x=5, y=7)
add(3, y=4)

我们定义了一个名为add的函数,它接受两个位置参数x和y,计算它们的和并打印结果。然后,我们通过调用add函数,并分别传递不同的位置和关键字参数来执行函数。

2.3.5 实参的总结

函数的实参是在调用函数时传递给函数的具体值或变量。实参可以通过位置参数或关键字参数进行传递,并且可以混合使用。此外,Python还支持可变数量的位置参数和关键字参数。

2.4 函数的返回值

函数的返回值是指在函数执行完毕后,通过return语句将结果返回给函数调用者。函数调用者可以使用这个返回值进行进一步的操作或处理。

2.4.1返回单个值:

函数可以返回一个单独的值,该值可以是任何有效的Python对象,例如数字、字符串、列表、字典等。
使用return语句后面跟着需要返回的值,例如return result。

2.4.2 返回多个值

在Python中,函数可以返回多个值。实际上,它返回的是一个元组,其中包含多个值。
可以使用逗号分隔多个值,并在return语句中返回它们,例如return value1, value2, …。
在函数调用时,可以将返回的多个值分配给多个变量,或者使用一个变量接收它们作为元组。

2.4.3 不带返回值

如果函数没有使用return语句来显式返回值,则默认返回None。
None是一个表示空值的特殊对象,在函数没有其他返回值时通常用作占位符。
下面是一个示例函数及其返回值的解释:

def add(x, y):
    """计算两个数的和,并返回结果"""
    result = x + y
    return result

# 调用函数并接收返回值
sum = add(2, 3)
print("和:", sum)

def get_info():
    """返回多个值"""
    name = "Alice"
    age = 25
    return name, age

# 调用函数并接收多个返回值
name, age = get_info()
print("姓名:", name)
print("年龄:", age)

在上述代码中,我们定义了一个名为add的函数,它接受两个参数x和y,计算它们的和并通过return语句返回结果。然后,我们调用add函数并将返回的结果赋值给变量sum,最后打印出结果
我们还定义了一个名为get_info的函数,它返回两个值name和age。在函数调用时,我们使用两个变量来接收返回的多个值,并分别打印出来。

2.4.4总结

函数的返回值是通过return语句将结果返回给函数调用者。可以返回单个值或多个值,并且可以在函数调用时将返回值分配给变量进行处理。

3. 变量的作用域

3.1全局作用域

在函数外部定义的变量拥有全局作用域,可以在程序的任何地方访问该变量。
在函数内部,可以通过global关键字来声明一个变量是全局变量,从而在函数内部对其进行修改。

x = 10  # 全局变量

def func():
    global x
    x = 5  # 将全局变量x修改为5
    print("函数内部:x =", x)

func()

print("函数外部:x =", x)
# 输出结果函数内部:x = 5 函数外部:x = 5

我们定义了一个全局变量x和一个名为func的函数。在函数内部,我们使用global关键字声明x为全局变量,并将其赋值为5。然后,在函数外部,我们打印出全局变量x的值,可以看到它已经被修改为5。
在函数内部使用global关键字声明变量后,该变量在函数内部的所有操作都会影响到全局变量。因此,在使用global关键字时需要小心,以免不小心修改了全局变量导致程序出现错误。

3.2局部作用域

在函数内部定义的变量拥有局部作用域,只能在函数内部访问该变量。
在函数外部不能访问函数内部的变量。

3.3嵌套作用域

如果在函数内部定义了另一个函数,则该函数内部的变量可以在嵌套函数或外部函数之间共享。

3.4 函数作用的总结

当在函数内部使用变量时,Python会首先在局部作用域中查找该变量,如果找不到则会在上一层嵌套作用域中查找,直至找到为止。如果在所有作用域中都找不到该变量,则会引发NameError异常。

x = 10  # 全局作用域

def func():
    y = 5  # 局部作用域
    print("函数内部:x =", x)  # 可以访问全局变量
    print("函数内部:y =", y)  # 可以访问局部变量

func()
# 输出结果
函数内部:x = 10
函数内部:y = 5
def outer_func():
    a = 1  # 外部函数局部作用域
    def inner_func():
        b = 2  # 内部函数局部作用域
        print("内部函数:a =", a)  # 可以访问外部函数局部变量
        print("内部函数:b =", b)  # 可以访问内部函数局部变量
    inner_func()

outer_func()
# 输出结果
内部函数:a = 1
内部函数:b = 2

在上述代码中,我们定义了一个全局变量x和一个名为func的函数,在函数内部定义了一个局部变量y。在函数内部,我们可以访问全局变量x和局部变量y。
我们还定义了一个名为outer_func的函数,其中包含一个内部函数inner_func。在内部函数中,我们可以访问外部函数的局部变量a和内部函数的局部变量b。
Python中的变量作用域可以分为全局作用域、局部作用域和嵌套作用域。在使用变量时,Python会按照一定的规则查找变量所在的作用域,找到后才能使用该变量。

4. 递归函数

1.递归函数必须具有终止条件,否则会导致无限递归,最终导致程序崩溃。
2.每次调用递归函数时,问题的规模都应该减小,否则会导致无限递归。

4.1 递归函数的例子

归根结底就是自己调用自己,而且就是有出口
下面是一个计算阶乘的递归函数示例:

def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

print(factorial(5))  # 输出 120

在上述代码中,我们定义了一个名为factorial的函数,用于计算阶乘。在函数内部,我们首先判断参数n是否为0,如果是,则返回1作为终止条件;否则,将n与factorial(n-1)的乘积作为返回值。这里的factorial(n-1)就是通过调用自身来完成规模不断缩小的过程。在计算阶乘时,我们可以调用factorial(5),得到结果120。
例如计算斐波那契数列:

def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(7))  # 输出 13

我们定义了一个名为fibonacci的函数,用于计算斐波那契数列。在函数内部,我们首先判断参数n是否小于等于1,如果是,则返回n作为终止条件;否则,将fibonacci(n-1)和fibonacci(n-2)的和作为返回值。这里的fibonacci(n-1)和fibonacci(n-2)就是通过调用自身来完成规模不断缩小的过程。在计算斐波那契数列时,我们可以调用fibonacci(7),得到结果13。
递归函数是一种特殊的函数,它会在函数内部调用自身。在使用递归函数时,需要注意必须具有终止条件,否则会导致无限递归,最终导致程序崩溃。递归函数通常用于解决可以被分解为多个相同问题的问题,例如计算阶乘、斐波那契数列等。

4.2递归函数的限制

4.2.1资源消耗

递归函数在每次调用自身时都会占用额外的内存空间,包括函数调用栈和局部变量。如果递归深度过大,可能会导致栈溢出的问题。因此,在设计递归函数时要注意控制递归深度,避免出现过多的递归调用。

4.2.2执行效率

相比循环迭代,递归函数的执行效率通常较低。这是因为每次调用递归函数都需要进行函数调用、参数传递等操作,而这些操作会带来一定的开销。对于一些简单的问题,使用递归函数可能没有明显的性能差异,但对于一些复杂的问题,使用递归函数可能会导致较长的执行时间。

4.2.3 增加递归深度限制

可以通过修改编程语言或环境的设置来增加递归函数的最大调用深度。例如,在Python中,默认的递归深度限制是1000,可以使用sys.setrecursionlimit()函数来修改这个限制。但需要注意的是,过大的递归深度可能导致栈溢出错误,因此修改时应慎重考虑。

总结来说能不用就不要用递归。

文章来源:https://blog.csdn.net/qq_49615704/article/details/135712574
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。