百木园-与人分享,
就是让自己快乐。

Python-函数定义详解

函数定义支持可变数量的参数。下面列出三种可以组合使用的形式。

1 默认值参数

为参数指定默认值,在调用函数时可以使用比定义时更少的参数。

def student_info(name, sex, age=18, score=100):
if sex == \'male\':
print(f\"{name} is {age} years old, his score is {score}\")
else:
print(f\"{name} is {age} years old, her score is {score}\")

该函数接收两个必选参数name 和 sex ,两个可选参数 age ,score 。该函数可用下列方式调用

  • 只传入必选参数

student_info(\'ZhangSan\', \'male\')
# zhangSan is 18 years old, his score is 100.

  • 传入一个可选参数

student_info(\'LiSi\', \'female\', 17)
# LiSi is 17 years old, her score is 100.

  • 传入所有实参

student_info(\'XiaoHong\', \'female\', 17, 99)
# XiaoHong is 17 years old, her score is 99.

2 关键字参数

kwarg=value 形式的 关键字参数 也可以用于调用函数。

def student_info(name, sex, age=18, score=100):
if sex == \'male\':
print(f\"{name} is {age} years old, his score is {score}\")
else:
print(f\"{name} is {age} years old, her score is {score}\")

使用了默认值参数的函数都可以通过kwarg=value 形式的关键字参数调用函数。该函数可以通过下列方式调用。

student_info(\'ZhangSan\', \'male\')
student_info(\'ZhangSan\', \'male\', age=17)
student_info(\'ZhangSan\', \'male\', score=99)
student_info(\'ZhangSan\', \'male\', age=19, score=98)
student_info(\'ZhangSan\', \'male\', score=95, age=20)

从上面调用函数的方式可以看出:

  • 关键字参数的顺序可以和定义的顺序不一致
  • 关键字参数必须放在位置参数之后

如果你想打乱所有参数的顺序,包括位置参数,那么你需要对所有参数使用kwarg=value 的方式来传入实参。如:

student_info(score=100, age=19, name=\'ZhangSan\', sex=\'malae\')

不能在一次调用中多次对同一个参数进行赋值(即使多次赋值都是同一个值):

student_info(\'ZhangSan\', \'male\', name=\'ZhangSan\')

这样是不被允许的。

**name

当最后一个形参为**name 形式时,接收一个字典,该字典包含与函数中已定义形参之外的所有关键字参数。**name可以和*name形参组合使用(注意:*name必须在**name前面),*name接收一个元组,该元组包含形参列表之外的位置参数。

其中**name接收的字典中数据的顺序和调用函数时实参传入的顺序一致。

3 特殊参数

默认情况下,参数可以按位置或显式关键字传递给 Python 函数。为了让代码易读、高效,最好限制参数的传递方式,这样,开发者只需查看函数定义,即可确定参数项是仅按位置、按位置或关键字,还是仅按关键字传递。需要使用/和*。

函数定义如下:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
----------- ----------- ----------
| | |
| | |
位置参数 位置参数或关键字参数 关键字参数

其中/ 和* 是可选的。

3.1 位置或关键字参数

当函数定义中未使用/和*时,参数可以按照位置或关键字传递给函数。

3.2 仅位置参数

特定形参可以标记为 仅限位置。仅限位置 时,形参的顺序很重要,且这些形参不能用关键字传递。仅限位置形参应放在 / (正斜杠)前。/ 用于在逻辑上分割仅限位置形参与其它形参。如果函数定义中没有 /,则表示没有仅限位置形参。

/ 后可以是 位置或关键字 或 仅限关键字 形参。

3.3 仅限关键字参数

把形参标记为仅限关键字,表明必须以关键字参数的形式传递该参数。

3.4 函数示例

def standard_arg(arg):
print(arg)

def pos_only_arg(arg, /):
print(arg)

def kwd_only_arg(*, arg):
print(arg)

def combined_example(pos_only, /, standard, *, kwd_only):
print(pos_only, standard, kwd_only)

第一个函数 standard_arg 的函数定义对调用的方式没有任何限制,可以按位置也可以按关键字传递参数:

standard_aeg(2)
standard_aeg(arg=2)

第二个函数 pos_only_arg 的函数定义中有 / ,且形参全在 / 之前定义,所以仅限使用位置参数。

pos_only_arg(3)
pos_only_arg(arg=3) # 无效的调用
# TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: \'arg\'

第三个函数 kwd_only_arg 的函数定义通过 * 表明仅限关键字参数。

kwd_only_arg(arg=5)
kwd_only_arg(5) # 无效的调用
# TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given

最后一个函数 combined_example 的函数定义中,使用了全部三种调用惯例:

  • 该函数接收三个参数
  • 第一个参数仅限位置参数
  • 第二个参数可使用位置或关键字参数
  • 第三个参数仅限关键字参数

combined_example(6, 7, kwd_only=8)
combined_example(6, standard=7, kwd_only=8)

下面的函数定义中,kwds 里面不能把 name 当做键。会与第一个参数 name 冲突。

def foo(name, **kwds):
print(name, **kwds)

foo(1, **{name: 2})

因为上面的函数调用相当于把name 赋值了两次。等价于:

foo(1, name=2)

由于此时name 既可以当作位置参数,也可以当作关键字参数,所以上述行为相当于给一个参数在一次函数调用中赋值了两次。

那么如何才能让 kwds 使用 name 当作键呢?

这就需要使用 特殊参数 / 来解决了,只要把 name 参数仅限使用位置参数,那么再使用name=2 时就不会被认为是第二次赋值了。

所以需要把函数定义为:

def foo(name, /, **kwds):
print(name, kwds)

foo(1, name=2, age=18)
# 1 {\'name\': 2, \'age\': 18}

就可以了。👼

总结:仅限位置形参的名称可以在**kwds中使用,而不产生歧义。

4 任意实参列表

调用函数时,使用任意数量的实参是最少见的选项。这些实参包含在元组中。

有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种 情况下,可将函数编写成能够接受任意数量的键值对——调用语句提供了多少就接受多少。

def sumnum(a, *ddd):
print(a)
result = a
for num in ddd:
result += num
return result
print(sumnum(1, 2, 3, 5, 6, 9, 8, 7))
# 1
# 41

*name 用于接收传递给函数的所有剩余位置参数,因此*name 的后面不允许出现位置参数,而是仅限关键字参数,同样的*name 的前面也不允许出现任何的关键字参数,而是仅限位置参数。

5 解包实参列表

函数调用要求独立的位置参数,但实参在列表或元组里时,要执行相反的操作。例如,内置的 range() 函数要求独立的 start 和 stop 实参。如果这些参数不是独立的,则要在调用函数时,用 * 操作符把实参从列表或元组解包出来:

>>> list(range(3, 6))
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))
[3, 4, 5]

同样,字典可以用 ** 操作符传递关键字参数。

6 Lambda 表达式

Lambda 关键字用于创建小巧的匿名函数。

Lambda a, b: a+b

上面的函数返回两个参数的和。Lambda 函数可用于任何需要函数对象的地方。在语法上,匿名函数只能是单个表达式。在语义上,它只是常规函数定义的语法糖。与嵌套函数定义一样,lambda 函数可以引用包含作用域中的变量:

def make_incrementor(n):
return lambda x: x + n

f = make_incrementor(42)
print(f(0))
# 42
print(f(1))
# 43

上例用 lambda 表达式返回函数。还可以把匿名函数用作传递的实参:

pairs = [(1, \'one\'), (2, \'two\'), (3, \'three\'), (4, \'four\')]
pairs.sort(key=lambda pa: pa[1])
print(pairs)
# [(4, \'four\'), (1, \'one\'), (3, \'three\'), (2, \'two\')]

来源:https://www.cnblogs.com/yuling25/p/15247764.html
图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Python-函数定义详解

相关推荐

  • 暂无文章