早知如此!来看看 Python 函数的七个秘密

上一篇 / 下一篇  2024-04-30 14:12:32

  Python 函数的七个重要知识点:类型提示以增加代码可读性;*args和**kwargs、Lambda函数和高阶函数提供代码灵活性;装饰器让我们无需修改原函数即可改变其行为;生成器函数实现惰性评估;最后,魔术方法在Python类中定义了特殊行为。这些知识点是每个Python开发者的必备工具。
  (1)类型提示
  下面的代码在工作中随处可见!
  def magic(a, b):
      return a + b
  我们可以轻易地编写如上的函数,因为 Python 是动态类型的——也就是说,变量数据类型是在运行时确定的。
  def magic(a: int, b: int) -> int:
      return a + b
  不过,也可以编写如上与先前完全相同,但带有类型提示的函数:
  ·a应为整数
  · b也应为整数
  · 函数的返回值应该是一个整数
  当代码库变的更大时,类型提示在保持代码尽可能地具有可读性方面变得越来越重要。想想看,有 10,000 个函数,你需要推断它们所接受的数据类型以及它们的返回类型,那就太“好玩”了。
  def test1(ls: list[int], x: float) -> list[float]:
      pass
  ls是整数列表,x应该是浮点数,函数应返回浮点数列表。
  def test2(a: str, b: bool, c: dict[str, str]) -> dict[str, int]:
      pass
  a应为字符串,b应为布尔值,c应为字典,其中键为字符串,值为字符串。返回值应为一个字典,其键为字符串,但值为整数。
  请注意:类型提示只是提示,并不强制执行。如果我们没有遵循类型提示给出的类型,Python 仍会允许这个操作。
  (2)*args 和 **kwargs
  在真实的开发中,会有大量的*args 和**kwargs参数:
  ·args* 允许函数接受无限数量的位置参数。
  · kwargs 允许函数接受无限数量的关键字参数。
  所有的位置参数都会被捕获为元组参数,所有的关键字参数都会被捕获为字典参数。
  magic(1, 2, 'apple', a=4, b=5, c=[1, 2, 3])
  ·1、2 和 'apple'是位置参数。
  · a=4、b=5 和 c=[1,2,3]是关键字参数。
  def magic(*args, **kwargs):
      print('args =', args)
      print('kwargs =', kwargs)
  magic(1, 2, 'apple', a=4, b=5, c=[1, 2, 3])
  # args = (1, 2, 'apple')
  # kwargs = {'a':4, 'b':5, 'c':[1, 2, 3]}
  ·所有位置参数都被捕获为元组参数。
  · 所有关键字参数都被捕获为字典参数。
  (3)Lambda 函数
  Lambda 函数是一种小型匿名函数。例如:
  def add(x, y):
      return x + y
  可以将它重写为 lambda 函数:
  add = lambda x, y: x + y
  函数的输入在":"之前,返回值在":"之后:
  # 另一个例子
  def add10(x):
      return x + 10
  # 等同于
  add10 = lambda x: x + 10
  Lambda 函数可以是匿名的,并且在需要将一个函数作为另一个函数的参数时,Lambda 函数可能非常有用:
  def apply(func, x):
      return func(x)
  x = apply(lambda x: x + 10, 7)
  print(x)  # 17
  (4)高阶函数
  高阶函数可以接受另一个函数作为参数,或者返回另一个函数,或者同时满足这两个条件。比如以下的 apply 函数:
  def apply(func, x):
      return func(x)
  x = apply(lambda x: x + 10, 7)
  print(x)  # 17
  在上述示例中,apply函数就是一个高阶函数,因为它接受了另一个函数即func作为参数。
  能熟练运用高阶函数,会让你的代码更为灵活强大。
  (5)装饰器
  装饰器是能够接受并返回函数的特殊高阶函数,它的目标是在不改变原函数源代码的情况下改变函数的行为。
  注意:装饰器函数既接受函数又返回函数。
  # 这是 decorator 函数
  def add_exclamation(func):
      def wrapper(name):
          return func(name) + '!'
      return wrapper
  # 这是被装饰的函数
  def hello(name):
      return 'hello ' + name
  # 实际的装饰动作在此进行
  hello = add_exclamation(hello)
  # 现在,我们的函数的行为略有变化
  print(hello('tom'))  # hello tom!
  我们可以用@add_exclamation替代hello=add_exclamation(hello),因为实际上它们做的事情是完全一样的。
  def add_exclamation(func):
      def wrapper(name):
          return func(name) + '!'
      return wrapper
  @add_exclamation
  def hello(name):
      return 'hello ' + name
  print(hello('tom'))  # hello tom!
  装饰器可以用于日志记录、计时、处理异常、验证身份、REST API等任务,是一个非常有用的工具!
  (6)生成器函数
  你是否曾遇到过这样的类似于<generator object x at 0x1029b4a90>的信息?当我们使用生成器函数时,就会出现这种情况。
  当我们使用yield时,函数就变成了生成器函数。yield和return关键字类似,都是从函数中输出一个值,但与return不同的是,yield并不会停止整个函数。
  # 常规函数
  def test():
      return [1, 2, 3]
  x = test()
  print(x)  # [1, 2, 3]
  # 生成器函数,但我们仍然称之为标准函数
  def test():
      yield 1
      yield 2
      yield 3
  x = test()
  print(x)  # <generator object x at 0x1029b4a90>
  # 生成器函数,但我们使用循环调用它
  def test():
      yield 1
      yield 2
      yield 3
  for i in test():
      print(i, end=' ')
  # 1 2 3
  生成器执行了惰性评估——也就是说,它只在绝对必要的情况下起作用(例如,当我们使用循环时)。这使代码在某些方面更为高效。
  (7)特殊的魔法(Dunder)方法
  这些在企业 Python 代码中也随处可见,特别是在涉及到面向对象编程时。魔术方法以两个下划线字符开始和结束,例如__init__,__str__,__getitem__,__add__等等。它们在 Python 类中定义了特殊行为。
  class Dog:
      # 定义如何为 dog 分配属性
      def __init__(self, name, age):
          self.name = name
          self.age = age
      # 定义当我们对 dog 执行 str() 时会返回什么
      def __str__(self):
          return 'Dog!'
      # 定义当我们执行 dog + something 时会返回什么
      def __add__(self, something):
          return 'Dog ' + str(something)
      # 定义当我们执行 dog[something] 时会返回什么
      def __getitem__(self, something):
          return 123
  了解更多的魔术方法可以让你的类更灵活,满足更多场景的需求。
  总结
  本文概述了 Python 函数的七个重要知识点:类型提示以增加代码可读性;*args和**kwargs、Lambda函数和高阶函数提供代码灵活性;装饰器让我们无需修改原函数即可改变其行为;生成器函数实现惰性评估;最后,魔术方法在Python类中定义了特殊行为。这些知识点是每个Python开发者的必备工具。
  希望这篇文章对你有所帮助,让你能更好地理解 python 函数。

TAG: 软件开发 Python

 

评分:0

我来说两句

Open Toolbar