一文带您精通Python 函数:全方位指南

liftword2个月前 (03-17)技术文章6

函数是编程中最为基本的构建单元,它们在组织代码和实现功能方面发挥着核心作用。Python 语言以其灵活性而著称,这种灵活性体现在函数定义和调用上。例如,Python 函数参数没有强制的类型约束,仅通过类型提示提供建议,这使得函数的定义和使用更加自由,但也增加了复杂性。

在 Python 中,函数参数的定义与使用极具灵活性,但也因此带来了一定的复杂性。Python 支持四种主要类型的参数:正常参数(normal arguments)、默认参数(default arguments)、任意位置参数(arbitrary positional arguments)以及任意关键字参数(arbitrary keyword arguments)。这种灵活性虽然极大地增加了函数的适用范围和便利性,但也可能造成一定的障碍。

  1. 正常参数 是最常见的参数形式,它们在函数定义时明确列出,并且在调用函数时必须提供相应的值。
  2. 默认参数 允许在函数定义时为参数指定默认值,这使得调用函数时可以省略这些参数,但这也可能导致函数行为的不明确性。
  3. 任意位置参数(通常以 *args 表示)允许函数接受任意数量的位置参数,这种灵活性可能使得函数的接口变得难以理解和使用。
  4. 任意关键字参数(通常以 **kwargs 表示)使得函数能够接受任意数量的关键字参数,这种特性虽然增强了函数的灵活性,但也增加了参数处理的复杂度。

这些参数类型虽然提供了强大的功能,但也可能使函数定义和调用变得复杂。在本文中,我们将详细探讨这些参数的特点与使用技巧,帮助您在充分利用 Python 函数灵活性的同时,减少可能遇到的障碍。

1.函数中的类型提示(Type hinting)

说实在的,我写过Python代码中,其实很少使用类型提示。为阅读和生成help 文档方便还是要认真编写类型提示和文档字符串的。

def avg(a: int,b: int)-> float:
  """
  Finds average of a and b  
  Args:
    a(int): an integer
    b(int):an integer
  Returns:
    (float):average of a and b
  """
  return (a+b)/2


print(avg(1,2))

  • a: int 表示理想情况下a应该是一个整数
  • b: int表示b理想情况下应该是一个整数
  • -> float表示该函数理想情况下应该返回一个浮点值

类型提示只是提示,并不强制语法约束。如果将字符串或其他数据类型传入ab, Python 实际上是可以接受的(直到它尝试将字符串除以 2 导致错误)

类型提示的目的更多是使代码更易于人类阅读和 IDE(例如 PyCharm 或 VSCode)能够为您进行检查。

2.默认参数(Default arguments)

def greet(name,greeting ='hi'):
  print(f"{greeting} {name}")

在上面的示例函数中,greeting='hi'是一个默认参数。

  • 如果不向greeting传递任何内容,则会自动赋值“hi”
  • 如果决定将某些内容传递给 greeting,它将采用该值
def greet(name,greeting ='hi'):
  print(f"{greeting} {name}")


greet("john")
greet("john",greeting="hello")
greet("john","HELLO")

如果函数中有大量参数,并且不希望每次调用该函数时都必须传递每个参数,那么这很有用。

3.参数和实参 Arguments VS Parameters

假设我们有一个简单的函数,它接受两个参数(Argument)(a 和 b)并返回它们的平均值。

  • 参数(Argument) 是在定义函数时写在括号内的变量。在下面的例子中,a 和 b 是参数。
  • 实参(Parameter) 是在调用函数时实际传递给函数的值。在下面的例子中,当我们调用 avg(a, b) 函数时,2和 4 是实参。
def avg(a,b):  # a b 是参数 Arguments 
  return (a+b)/2


x=avg(2,4)  # 3,4 是实参 Parameters
print(x)

4.位置参数和关键字参数(Positional VS Keyword Arguments)

def avg(a,b): 
  print(f"{a=}",f"{b=}")
  return (a+b)/2


avg(4,7)

4 和 7 是位置参数(positional arguments)。位置参数需要按照顺序传递——4 被传递给 a,而 7 被传递给 b。

def avg(a,b):
  print(f"{a=}",f"{b=}")
  return (a+b)/2


avg(b=5,a=8)

b=5 和 a=8 是关键字参数(keyword arguments)。关键字参数不需要按顺序传递,但必须使用 key=value 的格式传递。

5.任意位置参数 (*args)(Arbitrary Positional Arguments )

函数中的任意位置参数(Arbitrary positional arguments),也称为 *args,允许函数接受任意数量的位置参数。

def test(*args):
  print(args)


test()
test(1)
test(1,2)
test(1,2,3)
test(1,2,3,4)

test 函数接受 *args,这允许函数接收任意数量的位置参数,这些参数会被收集到一个名为 args 的元组中。

可以将 *args 与正常参数结合使用,但 *args 必须放在正常参数之后:

def test(a,b,*args):
  print(f"{a=} {b=}",args)


try:
  test()
except Exception as e:
  print(e)
try:
  test(1)
except Exception as e:
  print(e)
test(1,2)
test(1,2,3)
test(1,2,3,4)

PS:不一定要用 *args 这个名字。只要在参数名前加上 *,可以使用任何名称。

6.任意关键字参数 (kwargs)( Arbitrary keyword arguments )

任意关键字参数,也称为 **kwargs,允许我们的函数接收任意数量的关键字参数。

def test(**kwargs):
  print(kwargs)
  
test()
test(a=1)
test(b=2,a=1)

test 函数接受 **kwargs,这允许函数接收任意数量的关键字参数,这些参数会被收集到一个名为 kwargs 的字典中。

也可以将 **kwargs 与正常参数结合使用,但 **kwargs 必须放在正常参数之后:

def test(a,b,**kwargs):
  print(f"{a=} {b=}",kwargs)
  
try:
  test()
except Exception as e:
  print(e)
try:
  test(a=1)
except Exception as e:
  print(e)
test(b=2,a=1)
test(b=2,a=1,c=3)

PS:不必非要将其命名为 kwargs。只要在参数名前加上 **,可以使用任何名称。

7.使用 * 和 ** 将列表/字典传递给函数

使用 * 将包含位置参数的列表传递给函数:

def print_args(*args):
    print(args)


args_list = [1, 2, 3]
print_args(*args_list)

使用 ** 将包含关键字参数的字典传递给函数:

def print_kwargs(**kwargs):
    print(kwargs)


kwargs_dict = {'a': 1, 'b': 2, 'c': 3}
print_kwargs(**kwargs_dict)


函数是编程的基本单元,Python 的灵活性体现在其函数参数的多样性上,包括正常参数、默认参数、任意位置参数(*args)和任意关键字参数(**kwargs)。虽然这些特性增加了函数的灵活性和便利性,但也带来了复杂性。例如,*args 允许接收任意数量的位置参数,而 **kwargs 允许接收任意数量的关键字参数。通过适当使用这些参数类型,函数的定义和调用可以变得更强大和灵活,同时也需要注意参数的正确顺序和名称。

相关文章

Python 函数参数

1.函数基本参数#基本样例 函数参数的定义要和调用参数匹配,否则会报错 def fun01(a, b): print(a, b) if __name__ == '__main__':...

Python基础 - 函数的位置参数、关键字参数、默认参数

在 Python 中,调用函数可以按照函数的位置传递参数(位置参数),也可以按照参数的名称传递参数(关键字参数),函数的参数还可以在定义的时候指定默认值(默认参数)。此外,Python 还支持可变参数...

python之函数的参数详解

参数传递:1.不可变数据类型:数字number(含int、float、bool、complex)、字符串string、元组tuple。当不可变数据类型被当作函数的参数,传递的是值,函数体内改变值时实际...

真相!Python 默认值参数深度解析,从踩坑到精通的进阶秘籍

一、开发中遇到的问题问题 1:默认值参数为可变对象的陷阱在 Python 开发里,不少初学者会在默认值参数为可变对象时踩坑。比如,我们想定义一个函数,用于向列表中添加元素,代码如下:def add_t...

Python 函数之参数

定义一个函数非常简单,但是怎么定义一个函数,需要什么参数,怎么去调用却是我们需要去思考的问题。如同大多数语言一样(如 Java),Python 也提供了多种参数的设定(如:默认值参数、关键字参数、形参...

Python命令行参数解析模块argparse

前言以前 optparse 比较火,但是在python2.7版本后,官方不再维护这个模块,转而大力支持 argparse 。argparse 模块可以让人轻松编写用户友好的命令行接口。她可以从 sys...