7个必知Python函数特征

1) 函数中的类型提示

我刚开始学 Python 的时候,完全没用过类型提示。所以在最初的几年里写 Python 代码时,我一个类型提示都没加过。

举个简单的例子,假设我们要写一个函数来计算两个整数的平均值。以前我是这样写的:

def avg(a, b):
	return (a + b) / 2

现在我在工作中写函数的方式(添加了类型提示和文档字符串):

def avg(a: int, b: int) -> float:
    """
    计算 a 和 b 的平均值
    参数:
        a (int): 一个整数
        b (int): 一个整数
    返回:
        float: a 和 b 的平均值
    """
    return (a + b) / 2
  • a: int 意味着 a 最好是个整数
  • b: int 意味着 b 最好也是个整数
  • -> float 意味着函数最好返回一个浮点数值

不过,需要注意的是,类型提示只是提示,不会强制执行。如果我们传入字符串或其他数据类型到 a 和 b 中,Python 其实并不介意(直到它试图把字符串除以 2 时才会出错)

类型提示的主要作用是 1) 让人类更容易读懂代码,2) 让你的 IDE(比如 PyCharm 或 VSCode)能为你做检查。

尽可能地给你的函数添加类型提示,这样其他程序员(或者未来的自己)就能更容易理解这些函数了。

2) 默认参数

def greet(name, greeting='hi'):
    print(greeting, name)

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

  • 如果我们不给 greeting 传入任何值,它就默认被赋值为 'hi'
  • 如果我们决定给 greeting 传入某个值,那就用那个值
greet('汤姆')
# hi 汤姆

greet('汤姆', greeting='你好')
# 你好 汤姆

greet('汤姆') 中,我们没有给 greeting 传入任何值。这意味着它会采用默认值 'hi'

而在 greet('汤姆', greeting='你好') 中,我们给 greeting 传入了 '你好'。这就覆盖了默认参数,把 greeting 设定为 '你好'

如果你的函数有很多参数,又不想每次调用时都得传入所有参数的话,这招可真管用。

3) 参数与实参

在我刚开始学 Python 的头几年里,我一直以为这两个词是一个意思。

其实不然,它们之间还是有些微妙的区别。

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

def avg(a, b):
    return (a + b) / 2

参数是在定义函数时括号内写明的变量。这里,a 和 b 就是参数。

实参是我们调用函数时实际传入的值。当我们调用 avg(a, b) 函数时,3 和 5 就是实参。

4) 位置参数与关键字参数

一个简单的示例函数。

def test(a, b):
    print(f'a={a} b={b}')

我们先通过位置参数来调用这个函数。

test(4, 7) # a=4, b=7

这里,4 和 7 是位置参数。位置参数必须按顺序传递——4 被传给 a,而 7 则传给了 b。

接着,我们通过关键字参数来调用函数。

test(b=5, a=8) # a=8, b=5

这里,b=5a=8 是关键字参数。关键字参数不必按顺序传递,但必须以 键=值 的形式传入。

5) 任意数量的位置参数 (*args)

函数中的任意数量的位置参数,通常写作 *args,能让函数接收任意多个位置参数。

def test(*args):
    print(args)
    
test()  # 错误
test(1) # 错误

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

这里,test 函数使用 *args — 这意味着 test 可以接收任意数量的位置参数,这些参数会被收集到一个名为 args 的元组中。

我们可以把这个与普通参数结合使用(*args 必须放在后面)。

def test(a, b, *args):
    print([a, b], args)
    
test()  # 错误
test(1) # 错误

test(1, 2) # [1, 2], ()
test(1, 2, 3, 4) #[1, 2], (3, 4)

额外说明 — 我们不必非要用 *args,只要在前面加个星号就行。

6) 任意数量的关键字参数 (**kwargs)

任意数量的关键字参数,通常写作 **kwargs,能让我们的函数接收任意多个关键字参数。

def test(**kwargs):
    print(kwargs)
test() # {}
test(a=1) #{'a': 1}
test(a=1, b=2) #{'a': 1, 'b': 2}

这里,test 函数使用 **kwargs — 这意味着 test 可以接收任意数量的关键字参数,这些参数会被收集到一个名为 kwargs 的字典中。

我们也可以把这个与普通参数结合使用(**kwargs 也必须放在后面)。

额外说明 — 我们不必非得用 **kwargs,只要在前面加两个星号就行。

7) 使用 * 和 ** 传递列表/字典到函数中

这里有一个简单的函数,用来打印出它的参数。

def hi(a, b):
    print(f'{a=} {b=}')

除了像 hi(1, 2) 这样正常调用函数外,我们还可以:

  1. 使用 * 来传递包含位置参数的列表
def hi(a, b):
    print(f'{a=} {b=}')

nums = [100, 200]

hi(*nums)

这里,*nums 前面的星号将列表的内容展开为位置参数。这就相当于 hi(100, 200)

  1. 使用 ** 来传递包含关键字参数的字典
def hi(a, b):
    print(f'{a=} {b=}')

nums = {'a': 100, 'b': 10}

hi(**nums)

这里,**nums 前面的两个星号将字典的键值对展开为关键字参数。这就相当于 hi(a=100, b=10)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值