VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > python入门教程 >
  • Python-函数定义详解

1 默认值参数

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

python
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 。该函数可用下列方式调用

  • 只传入必选参数
python
student_info('ZhangSan', 'male')
# zhangSan is 18 years old, his score is 100.
  • 传入一个可选参数
python
student_info('LiSi', 'female', 17)
# LiSi is 17 years old, her score is 100.
  • 传入所有实参
python
student_info('XiaoHong', 'female', 17, 99)
# XiaoHong is 17 years old, her score is 99.

2 关键字参数

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

python
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 形式的关键字参数调用函数。该函数可以通过下列方式调用。

python
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 的方式来传入实参。如:

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

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

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

这样是不被允许的。

**name

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

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

3 特殊参数

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

函数定义如下:

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

其中/ 和是可选的。

3.1 位置或关键字参数

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

3.2 仅位置参数

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

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

3.3 仅限关键字参数

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

3.4 函数示例

python
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 的函数定义对调用的方式没有任何限制,可以按位置也可以按关键字传递参数:

python
standard_aeg(2)
standard_aeg(arg=2)

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

python
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 的函数定义通过 * 表明仅限关键字参数。

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

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

  • 该函数接收三个参数
  • 第一个参数仅限位置参数
  • 第二个参数可使用位置或关键字参数
  • 第三个参数仅限关键字参数
python
combined_example(6, 7, kwd_only=8)
combined_example(6, standard=7, kwd_only=8)

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

python
def foo(name, **kwds):
  	print(name, **kwds)
    
foo(1, **{name: 2})

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

python
foo(1, name=2)

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

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

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

所以需要把函数定义为:

python
def foo(name, /, **kwds):
  	print(name, kwds)
    
foo(1, name=2, age=18)
# 1 {'name': 2, 'age': 18}

就可以了。


相关教程