Python函数编程

函数的基本使用

在Python中,函数是一段可重复使用的代码块,用于执行特定的任务或完成特定的操作。函数能够接受输入参数,执行特定的逻辑,并返回一个结果。下面是函数的一些重要知识点:

定义与调用

  • 函数的定义使用关键字def,后面跟着函数名、参数列表和冒号。函数体在缩进块中。
  • 函数的调用通过函数名加括号的形式实现。
python
def greet(name):
    print("Hello, " + name)

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

函数的参数

  • 形式参数(形参):在函数定义时用来接收传入的值的参数。可以是必需参数或可选参数。
  • 实际参数(实参):在函数调用时传递给函数的值。
  • 函数可以有多个参数,包括位置参数、默认参数和可变参数。
python
def add(x, y):  # 位置参数
    return x + y

def greet(name, greeting="Hello"):  # 默认参数
    print(greeting + ", " + name)

def multiply(*nums):  # 可变参数
    result = 1
    for num in nums:
        result *= num
    return result

sum = add(3, 5)              # 调用函数 add,返回 8
greet("Alice")               # 调用函数 greet,输出:Hello, Alice
greet("Bob", "Hi")           # 调用函数 greet,输出:Hi, Bob
product = multiply(2, 3, 4)  # 调用函数 multiply,返回 24

注意:函数调⽤时,==如果有位置参数时,位置参数必须在关键字参数的前⾯==,但关键字参数之间不存在先后顺序。

参数的传递方式

在Python中,函数参数的传递方式可以分为值传递和引用传递。理解函数参数的传递方式很重要,因为它涉及到函数对参数的修改是否会影响原始数据。

下面是关于值传递和引用传递的详细介绍以及相关的注意事项(==准确来说我们应该关注可变对象和不可变对象在作为函数参数传递时的不同表现==):

  1. 值传递(Pass by Value):

    • 值传递是指将实际参数的值复制一份,传递给函数的形式参数。在函数内部对形式参数的修改不会影响原始数据。

    • 值传递适用于不可变对象,如数字、字符串和元组等。

      python
      def change_value(num):
          num = 10
      
      value = 5
      change_value(value)
      print(value)  # 输出:5,原始数据不受函数修改影响
  2. 引用传递(Pass by Reference):

    • 引用传递是指将实际参数的引用(内存地址)传递给函数的形式参数。在函数内部对形式参数的修改会影响原始数据。

    • 引用传递适用于可变对象,如列表、字典和集合等。

      python
      def change_list(lst):
          lst.append(4)
      
      my_list = [1, 2, 3]
      change_list(my_list)
      print(my_list)  # 输出:[1, 2, 3, 4],原始数据受函数修改影响
  3. 注意事项:

    • 对于不可变对象(如数字、字符串、元组),函数内部对形式参数的修改不会影响原始数据。
    • 对于可变对象(如列表、字典、集合),函数内部对形式参数的修改会影响原始数据。
    • 在函数内部,可以通过赋值操作来创建新的可变对象,以避免影响原始数据。
    • 在函数调用时,传递不可变对象的值本身,并不会改变原始数据的值。
    • 在函数调用时,传递可变对象的引用,函数内部对引用进行操作会改变原始数据的内容。

作用域和变量

  • 函数内部可以访问外部作用域的变量,但不能直接修改外部作用域的变量(除非使用global关键字)。
  • 局部变量是在函数内部定义的变量,只在函数内部可见。
  • 全局变量是在函数外部定义的变量,可以在整个程序中访问。
python
def greet():
    message = "Hello"  # 局部变量
    print(message
name = "Alice"        # 全局变
greet()               # 调用函数 greet,输出:Hello
print(name)           # 输出:Alice

函数的返回值

  • 函数可以使用return语句返回一个值。如果函数没有明确的返回语句,将返回None
  • 可以返回单个值、多个值(以元组形式返回)、或者使用关键字参数返回字典。
python
 def add(x, y):
     return x + y
 def divide(dividend, divisor):
     quotient = dividend // divisor
     remainder = dividend % divisor
     return quotient, remainder
 def get_info():
     return {"name": "Alice", "age": 25}
 sum = add(3, 5)                # 调用函数 add,返回 8
 result = divide(10, 3)         # 调用函数 divide,返回 (3, 1)
 info = get_info()              # 调用函数 get_info,返回 {"name": "Alice", "age": 25}

Python函数文档

在Python中,函数文档是用于描述函数的目的、输入参数、输出结果和使用方法的字符串。它提供了函数的说明和使用示例,帮助其他开发者理解和正确使用函数。下面是详细介绍函数文档及相关注意事项的内容:

  1. 函数文档的编写:

    • 函数文档通常位于函数定义的下一行,并使用三引号('''""")括起来。
    • 函数文档应该清晰、简洁地描述函数的功能、输入参数、返回值和使用方法。
    • 可以使用适当的标记和格式化方式,如段落、列表、代码块等,以提高可读性。
      python
      def add(x, y):
          """
          函数 add 实现了两个数相加的功能。
      
          参数:
          x -- 第一个操作数
          y -- 第二个操作数
      
          返回值:
          两个数的和
      
          使用示例:
          result = add(3, 5)
          print(result)  # 输出:8
          """
          return x + y
  2. 使用help()函数查看函数文档:

    • Python提供了内置的help()函数,用于查看函数的文档字符串。
    • 可以在交互式解释器或脚本中使用help()函数来获取函数的说明和使用示例。
      python
      help(add)  # 查看函数 add 的文档
  3. 注意事项:

    • 函数文档是代码的重要组成部分,应当养成良好的编写函数文档的习惯。
    • 函数文档应该提供足够的信息,以便其他开发者理解函数的用途和正确使用方式。
    • 函数文档应该及时更新,以反映函数的最新变化和功能。
    • 在编写函数文档时,可以考虑使用一些标准的文档约定和规范,如Google风格、Numpy风格等。
    • 函数文档的编写是一种良好的编码实践,它可以提高代码的可维护性和可读性。

函数文档是Python代码中重要的注释和说明,它可以帮助开发者更好地理解和使用函数。合理编写函数文档有助于提高代码质量,促进团队协作和代码复用。

递归函数

递归函数是指在函数的定义中调用函数本身的过程。Python允许使用递归函数来解决一些需要重复执行相同操作的问题。下面是有关递归函数的详细介绍及相关的注意事项:

递归函数的定义:

  • 在函数的定义中调用函数本身,以实现问题的分解和求解。

  • 递归函数必须包含终止条件,即递归的停止条件,否则会陷入无限递归的循环中。

    python
    def factorial(n):
        if n == 0:  # 终止条件
            return 1
        else:
            return n * factorial(n - 1)  # 递归调用
    
    result = factorial(5)  # 计算 5 的阶乘,返回 120

递归函数在解决一些问题时非常有用,尤其是问题可以自然地分解成较小的子问题的情况。但是,需要小心处理递归的终止条件和问题规模的减小,以避免无限递归和性能问题。 在使用递归函数时,要根据具体情况进行权衡,并确保代码的正确性和可读性。

Lambda函数

Lambda函数是一种匿名函数,也称为"lambda表达式"。它是一种简洁的定义函数的方式,可以在需要函数的地方使用,并且不需要为函数命名。下面是有关Lambda函数的详细介绍及相关的注意事项:

  1. Lambda函数的语法:

    • Lambda函数的语法格式为:lambda 参数: 表达式

    • Lambda函数可以有多个参数,用逗号分隔。

    • 表达式是函数的返回值,可以是任意有效的表达式。

      python
      # 计算两个数的和
      add = lambda x, y: x + y
      result = add(3, 5)  # 返回 8
      
      # 判断一个数是否为偶数
      is_even = lambda num: num % 2 == 0
      even = is_even(6)  # 返回 True
  2. Lambda函数的特点:

    • Lambda函数是一种匿名函数,不需要为函数命名,可以直接在需要的地方定义和使用。
    • Lambda函数通常用于简单的函数操作,可以替代一些简单的函数定义。
    • Lambda函数可以作为参数传递给其他函数,如高阶函数的参数。
    • Lambda函数的定义比较简洁,适用于简单的函数逻辑,不适合复杂的函数定义。

Lambda函数在某些情况下非常有用,特别是在需要简洁定义函数或传递简单函数逻辑的场景中。然而,需要根据具体的需求和复杂性,权衡Lambda函数的可读性和使用常规函数定义的可维护性。

Python高阶函数

在Python中,函数是一等公民,可以作为参数传递给其他函数,也可以作为另一个函数的返回值。这种方式常用于函数式编程和高阶函数的应用。

高阶函数是指接受一个或多个函数作为参数,并/或返回一个函数作为结果的函数。Python中支持高阶函数的特性,可以方便地进行函数的组合、转换和扩展。

python
def add(x, y):
    return x + y

def apply_operation(operation, x, y):
    return operation(x, y)

sum = apply_operation(add, 3, 5)  # 调用函数 apply_operation,返回 8

下面将介绍python有关常用内置高阶函数的用例

map(func, iter)

map(function, iterable):将函数应用于可迭代对象的每个元素,并返回一个新的可迭代对象。

python
numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x**2, numbers)
# 返回 [1, 4, 9, 16, 25]

注意:函数参数必须接受一个输入,并返回一个输出。

filter(func, iter)

filter(function, iterable):根据函数的返回值筛选可迭代对象中的元素,并返回一个新的可迭代对象。

python
numbers = [1, 2, 3, 4, 5]
evens = filter(lambda x: x % 2 == 0, numbers)
# 返回 [2, 4]

注意:函数参数必须返回一个布尔值

reduce(func, iter)

reduce(function, iterable[, initializer]):对可迭代对象中的元素依次应用函数,进行累积操作,并返回最终结果。

python
from functools import reduce
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda x, y: x + y, numbers)
# 返回 15

注意:函数参数必须接受两个输入,并返回一个输出。

sorted(iter)

sorted(iterable[, key][, reverse]): 对可迭代对象进行排序,并返回一个新的列表。

python
numbers = [5, 2, 1, 3, 4]
sorted_numbers = sorted(numbers)
# 返回 [1, 2, 3, 4, 5]

注意:key参数可以指定一个函数,用于排序时的自定义比较规则。

functools.partial

functools.partial(func, *args, **kwargs): 返回一个新的函数对象,固定部分函数参数的值,方便进行函数的重用和扩展。

python
from functools import partial
def multiply(x, y):
    return x * y
double = partial(multiply, 2)
result = double(5)
# 返回 10

注意:partial函数可以固定部分函数参数的值,生成一个新的函数对象。