Python基础:函数

打印 上一主题 下一主题

主题 537|帖子 537|积分 1611

注意此篇文章适合基础不好的同学来看,如果是大佬只能作为知识总结,可以去学习更难的内容。祝你学习愉快!
在编程中,函数是一段代码的封装,具有特定的功能,可以被重复调用这段代码。函数使代码更加模块化、易于维护和重用。在Python中,函数是通过 def 关键字定义的。
1. 函数的定义



  • 函数定义使用 def 关键字,后跟函数名、参数列表(可选)和冒号 :。函数体包罗在缩进块中,表现函数的详细实现。
  • 根本语法
    1. def function_name(parameters):
    2.     # 函数体
    3.     return value  # 可选,返回值
    复制代码
  • 例子
    1. def greet(name):
    2.     print(f"Hello, {name}!")
    复制代码
    在这个例子中,greet 是函数名,name 是参数。函数体中有一个 print() 函数,用于输出问候信息。
2. 函数的调用



  • 函数定义(必须先定义再使用)后,可以通过函数名和传入参数来调用它。
  • 例子
    1. greet("Alice")  # 此处没有考虑返回值
    复制代码
    这会输出 “Hello, Alice!”。

3. 参数和返回值



  • 参数:函数可以担当多个参数,这些参数在函数调用时传入。
  • 返回值:函数可以返回一个值给调用者,使用 return 关键字。如果没有 return,函数默认返回 None。Python中的参数和返回值和有些语言不一样,会主动推断它们范例,不必要显式去写。
  • 例子
    1. def add(a, b):
    2.     return a + b
    3. result = add(3, 4)
    4. print(result)  # 输出: 7
    复制代码
3.1 形参和实参

形参(形式参数)



  • 定义:形参是在函数定义时使用的参数。它们是占位符,用于接收函数调用时传递给函数的数据。
实参(实际参数)



  • 定义:实参是在函数调用时传递给函数的实际值。它们是传递给函数的详细数据。
形参和实参的关系



  • 在函数调用时,实参的值会赋给对应的形参,实参的个数和形参要匹配。形参在函数内部使用,而实参是在函数外部传递的实际数据。
  • 例子
    1. def add(a, b):  # 形参 a 和 b
    2.     return a + b
    3. result = add(3, 4)  # 实参 3 和 4
    4. print(result)  # 输出: 7
    复制代码
在这个例子中,a 和 b 是形参,它们在函数 add 的定义中。调用 add(3, 4) 时,实参 3 被传递给 a,实参 4 被传递给 b,然后函数返回它们的和。
3.2 默认参数值



  • 在定义函数时,可以为参数指定默认值。如果调用时没有提供该参数,函数会使用默认值。有点类似C++中的缺省参数。
  • 例子
    1. def greet(name="stranger"):
    2.     print(f"Hello, {name}!")
    3. greet()  # 输出: "Hello, stranger!"
    4. greet("Bob")  # 输出: "Hello, Bob!"
    复制代码
3.3. 关键字参数



  • 函数调用时,可以使用 参数名=值 的形式指定参数,称为关键字参数。这样可以使参数的顺序不那么紧张。
  • 例子
    1. def describe_person(name, age):
    2.     print(f"{name} is {age} years old.")
    3. describe_person(age=30, name="Alice")
    4. # 输出: "Alice is 30 years old."
    复制代码
3.4. 可变参数



  • *args:函数可以担当任意数目的位置参数,使用 *args。args 是一个元组,包罗全部传递的位置参数。
  • **kwargs:函数可以担当任意数目的关键字参数,使用 **kwargs。kwargs 是一个字典,包罗全部传递的关键字参数。
  • 例子
    1. def sum_all(*args):
    2.     total = 0
    3.     for num in args:
    4.         total += num
    5.     return total
    6. print(sum_all(1, 2, 3, 4))  # 输出: 10
    7. def print_info(**kwargs):
    8.     for key, value in kwargs.items():
    9.         print(f"{key}: {value}")
    10. print_info(name="Alice", age=30, city="New York")
    11. # 输出:
    12. # name: Alice
    13. # age: 30
    14. # city: New York
    复制代码

4. 函数的作用域



  • 局部变量:在函数内部定义的变量是局部变量,只能在函数内部访问。
  • 全局变量:在函数外部定义的变量是全局变量,可以在函数内部访问和修改。
  • 例子
    1. x = 10  # 全局变量
    2. def change_x():
    3.     global x
    4.     x = 20  # 修改全局变量
    5. change_x()
    6. print(x)  # 输出: 20
    复制代码
它们之间的定名可以重复,如果辩论了以局部的为优先,但是一般不建议这么做。
5. 匿名函数(Lambda 函数)



  • 定义:Python 支持一种简短的函数定义方式,称为 lambda 函数。lambda 函数用于创建小型、单行匿名函数。
  • 语法
    1. lambda arguments: expression
    复制代码
  • 例子
    1. add = lambda x, y: x + y
    2. print(add(3, 4))  # 输出: 7
    复制代码
    lambda 函数通常在必要简单函数而不想定名时使用,如在排序、过滤等操纵中。

6. 函数的嵌套与闭包



  • 嵌套函数:可以在一个函数内部定义另一个函数。
  • 闭包:如果一个内部函数引用了外部函数的变量,而且外部函数的作用域已经结束,那么这个内部函数就被称为闭包。
  • 例子
    1. def outer_function(msg):
    2.     def inner_function():
    3.         print(msg)
    4.     return inner_function
    5. greet = outer_function("Hello")
    6. greet()  # 输出: "Hello"
    复制代码
7. 链式调用



  • 例子
  1. # 判定是否是奇数
  2. def isOdd(num):
  3.     if num % 2 == 0:
  4.         return False
  5.     else:
  6.         return True
  7.   
  8. result = isOdd(10)
  9. print(result)
复制代码
链式写法:
  1. print(isOdd(10))
复制代码
把一个函数的返回值, 作为另一个函数的参数, 这种操纵称为 链式调用

8. 函数递归(难点)

递归是一种在编程中常用的技术,它指的是函数调用自身来解决问题。递归通常用于将一个复杂问题分解成较小的相似问题,从而通过解决这些较小问题来解决原问题。这部分可以先跳过,等有了肯定的代码履历后再回来看。
8.1 递归的根本概念



  • 定义:递归函数是一个会在其定义内部调用自身的函数。
  • 布局:递归一般有两个部分:

    • 基准情形(Base Case):用于终止递归的条件,当满意这个条件时,递归停止。
    • 递归情形(Recursive Case):函数继续调用自身来解决问题的更小部分。

  • 例子:盘算阶乘
    1. def factorial(n):
    2.     if n == 1:  # 基准情形
    3.         return 1
    4.     else:
    5.         return n * factorial(n - 1)  # 递归情形
    6. print(factorial(5))  # 输出: 120
    复制代码
在这个例子中,factorial() 函数盘算数字 n 的阶乘。如果 n 是 1,则返回 1(基准情形);否则,函数调用自身盘算 n-1 的阶乘,并将结果乘以 n。
8.2 递归的长处



  • 简洁性:递归通常能使代码更加简洁和易于明白,特别是当问题本身具有递归性质时(例如树布局遍历、数学归纳等)。
  • 天然表达:递归可以或许天然地表达某些问题的布局,使代码与问题的数学描述更一致。
  • 解决复杂问题:递归可以或许轻松解决某些分治问题或与树、图等布局相关的问题。
8.3 递归的缺点



  • 性能问题:递归的每次调用都会在内存中保留当前函数的状态,这可能会导致较高的内存斲丧,特别是在递归深度较大的情况下容易导致栈溢出。
  • 服从低:有些递归算法可能会重复盘算相同的子问题,导致时间复杂度急剧上升,例如未经优化的斐波那契数列盘算。
  • 明白难度:对于不认识递归的人来说,递归的逻辑可能较难明白,特别是当递归深度较深或涉及复杂的条件判定时。
例子:未优化的斐波那契递归函数的服从问题
  1. # 计算斐波那契数列的第40项
  2. print(fibonacci(40))  # 运行时间可能非常长
复制代码
由于递归未优化,fibonacci(40) 必要大量重复盘算,服从极低。
8.4 递归的优化



  • 记忆化:通过缓存已盘算的结果来避免重复盘算,这种技术被称为记忆化或动态规划。
  • 转换为迭代:对于某些递归问题,可以将递归转换为迭代来避免栈溢出问题。
例子:使用记忆化优化斐波那契数列(这部分必要等学习了动态规划部分更好明白)
  1. def fibonacci_memo(n, memo={}):
  2.     if n in memo:
  3.         return memo[n]
  4.     if n <= 1:
  5.         return n
  6.     memo[n] = fibonacci_memo(n-1, memo) + fibonacci_memo(n-2, memo)
  7.     return memo[n]
  8. print(fibonacci_memo(40))  # 运行速度显著提升
复制代码
8.5 总结



  • 递归是一个强盛的工具,特别适用于分治问题、树布局操纵和天然递归问题。
  • 它具有简洁性和天然表达的长处,但也存在性能和内存斲丧的问题。
  • 通过优化技术,如记忆化或将递归转化为迭代,可以或许有效改善递归的缺点。
函数是Python编程的核心之一,通过明白和使用函数,你可以编写出模块化、可重用和高效的代码。如果对你有资助不妨点个赞支持一下~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表