深入理解 Python 中的函数参数传递机制

发表于:2023-9-15 10:30

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:小小张说故事    来源:稀土掘金

  在 Python 中,对于函数的参数传递,有两种主要的方式:传值和传引用。事实上,Python 的参数传递是一种“传对象引用”的方式。接下来的文章我们将详细介绍 Python 的函数参数传递机制,这对理解 Python 编程语言的底层实现以及优化你的代码都非常有帮助。
  一、Python 中的变量和对象
  在深入理解参数传递之前,我们首先需要理解 Python 中的变量和对象的概念。
  在 Python 中,所有的数据都是对象,无论是数字、字符串还是自定义类型。而变量则是指向对象的引用。
  x = 3
  y = x
  在这个例子中,x 和 y 都是指向整数 3 这个对象的引用。我们可以通过 id() 函数查看它们指向的对象的内存地址,验证这一点。
  print(id(x))  # 输出:94832830448320
  print(id(y))  # 输出:94832830448320
  二、可变对象和不可变对象
  在 Python 中,对象可以分为可变对象和不可变对象。例如,列表、字典和集合是可变对象,而数字、字符串和元组是不可变对象。
  对于不可变对象,我们无法改变对象自身,但是可以改变变量所指向的对象。
  x = 3
  print(id(x))  # 输出:94832830448320
  x = 4
  print(id(x))  # 输出:94832830448352
  在这个例子中,我们先是让变量 x 指向了整数 3,然后又让 x 指向了整数 4。我们无法改变整数 3 自身,但是可以改变 x 所指向的对象。
  对于可变对象,我们既可以改变对象自身,也可以改变变量所指向的对象。
  x = [1, 2, 3]
  print(id(x))  # 输出:139644486420232
  x.append(4)
  print(id(x))  # 输出:139644486420232
  x = [1, 2, 3, 4, 5]
  print(id(x))  # 输出:139644486437576
  在这个例子中,我们先是让变量 x 指向了一个列表 [1, 2, 3],然后我们通过 append() 方法改变了这个列表,使其变为了 [1, 2, 3, 4]。此时,x 所指向的对象并没有改变,但是对象自身发生了变化。然后,我们让 x 指向了一个新的列表 [1, 2, 3, 4, 5]。此时,x 所指向的对象改变了。
  理解可变对象和不可变对象的区别,对于我们正确理解 Python 变量和函数的行为,以及编写正确、有效的代码都是非常重要的。
  三、参数传递机制
  在 Python 中,函数参数的传递遵循“传对象引用”的方式。对于可变对象和不可变对象,表现出来的效果类似传值和传引用。
  1. 不可变对象的参数传递
  当我们将一个不可变对象作为参数传递给函数时,函数内部无法改变这个对象自身。函数如果对这个参数进行改变,实际上是创建了一个新的对象。
  def change(n):
      print(id(n))
      n = 1000
      print(id(n))
  x = 3
  print(id(x))
  change(x)
  print(x)
  在这个例子中,函数 change() 试图改变参数 n。但是因为 n 是一个不可变对象,所以函数内部其实创建了一个新的对象,而原来的对象并没有改变。
  2. 可变对象的参数传递
  当我们将一个可变对象作为参数传递给函数时,函数内部可以改变这个对象自身。
  def change(n):
      print(id(n))
      n.append(4)
  x = [1, 2, 3]
  print(id(x))
  change(x)
  print(x)
  在这个例子中,函数 change() 改变了参数 n。因为 n 是一个可变对象,所以函数内部的改变影响到了原来的对象。
  四、函数参数传递机制的实际应用
  理解了 Python 的参数传递机制,有助于我们编写出更好的代码。例如,如果我们知道一个函数内部会改变传入的可变对象,我们可能需要在传入参数之前先创建一个副本。
  def change(n):
      n.append(4)
  x = [1, 2, 3]
  change(x[:])
  print(x)
  在这个例子中,我们传入了 x 的副本,因此函数内部的改变不会影响到 x。
  总的来说,Python 的函数参数传递机制遵循“传对象引用”的方式,理解这一点,能帮助我们更好的理解 Python 的工作原理,并编写出更有效率和可读性更强的代码。
  五、匿名函数 lambda
  Python 中的 lambda 是一个非常实用的匿名函数工具,它允许我们快速定义简单的函数。
  # 使用lambda定义一个匿名函数
  square = lambda x: x**2
  print(square(5))  # 输出:25
  在这个例子中,我们使用 lambda 关键字定义了一个匿名函数,该函数接收一个参数 x 并返回 x 的平方。
  1. lambda 的应用场景
  虽然 lambda 函数功能有限(只能写在一行上,不能包含复杂的逻辑),但在某些情况下,它的使用可以让代码更简洁。例如,当我们需要传入一个小的、临时的函数作为其他函数的参数时,就可以使用 lambda。
  # 使用lambda在列表排序中实现自定义排序规则
  data = [{'name':'Alan', 'age':20}, {'name':'Lisa', 'age':18}, {'name':'Tom', 'age':22}]
  data.sort(key=lambda x: x['age'])
  print(data)
  # 输出:[{'name': 'Lisa', 'age': 18}, {'name': 'Alan', 'age': 20}, {'name': 'Tom', 'age': 22}]
  在这个例子中,我们使用 lambda 函数作为 sort() 函数的 key 参数,来实现根据年龄的排序。
  六、函数式编程工具
  Python 提供了一些内建函数,用于支持函数式编程,如 map()、filter() 和 reduce() 等。这些函数可以用来对列表或其他可迭代对象进行操作,而无需编写循环。
  1. map() 函数
  map() 函数接收一个函数和一个可迭代对象作为参数,并将该函数应用于可迭代对象的每个元素,然后返回一个新的可迭代对象。
  # 使用map()函数将列表中的每个元素平方
  nums = [1, 2, 3, 4, 5]
  squares = map(lambda x: x**2, nums)
  print(list(squares))  # 输出:[1, 4, 9, 16, 25]
  在这个例子中,我们使用 map() 函数和一个 lambda 函数,将列表中的每个元素平方。
  2. filter() 函数
  filter() 函数接收一个函数和一个可迭代对象作为参数,并返回一个新的可迭代对象,该对象包含所有使该函数返回 True 的元素。
  # 使用filter()函数筛选出列表中的偶数
  nums = [1, 2, 3, 4, 5]
  evens = filter(lambda x: x % 2 == 0, nums)
  print(list(evens))  # 输出:[2, 4]
  在这个例子中,我们使用 filter() 函数和一个 lambda 函数,筛选出列表中的偶数。
  了解和掌握 Python 函数的这些特性,可以帮助我们编写出更加灵活、有效和简洁的代码。在未来的学习和工作中,我们还将遇到更多关于函数的应用场景,如装饰器、生成器等等,这些都可以看作是 Python 函数特性的延伸和应用。
  七、高阶函数
  在 Python 中,函数是第一类对象,这意味着我们可以将函数作为参数传递给其他函数,也可以让函数返回另一个函数。这样的函数,我们通常称之为高阶函数。高阶函数是函数式编程中的重要概念。
  1. 函数作为参数
  # 定义一个函数,接受另一个函数作为参数
  def apply_func(func, x):
      return func(x)
  # 定义一个函数,计算平方
  def square(x):
      return x ** 2
  print(apply_func(square, 5))  # 输出:25
  在这个例子中,apply_func 是一个高阶函数,它接收另一个函数 square 作为参数。
  2. 函数作为返回值
  # 定义一个函数,返回另一个函数
  def get_func(power):
      def power_func(x):
          return x ** power
      return power_func
  square = get_func(2)
  print(square(5))  # 输出:25
  在这个例子中,get_func 是一个高阶函数,它返回一个新的函数 power_func。
  高阶函数为我们的代码提供了很大的灵活性。例如,我们可以根据需要动态创建和修改函数,也可以构建更加复杂的函数逻辑。
  八、总结
  函数是 Python 编程的基础之一,掌握 Python 函数的各种特性和用法对我们的编程技能提升非常重要。通过本篇文章,我们对 Python 函数的基本概念和用法进行了回顾,并学习了 Python 中一些更高级的函数特性和用法,包括默认参数、可变参数、lambda 表达式、高阶函数等等。希望这些内容对你有所帮助,祝你在 Python 编程的道路上越走越远。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号