python-函数参数

函数参数

Python 的函数具有非常灵活多样的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。从简到繁的参数形态如下:

  • 位置参数 (positional argument)
  • 默认参数 (default argument)
  • 可变参数 (variable argument)
  • 关键字参数 (keyword argument)
  • 命名关键字参数 (name keyword argument)
  • 参数组合

一、位置参数

def functionname(arg1):

       "函数_文档字符串"

       function_suite

       return [expression]

  • arg1 - 位置参数 ,这些参数在调用函数 (call function) 时位置要固定。
    这段代码定义了一个名为 functionname 的函数,它接受一个位置参数 arg1

函数体包括一个文档字符串和一个函数体代码(称为 functionsuite)。文档字符串是对函数功能和使用方法的描述,位于函数定义的第一行,用于提供关于函数的说明和帮助。

函数执行完成后,可能会使用 return 语句返回一个表达式的值(可选)。如果在函数体中没有 return 语句或者没有指定返回值,函数将返回 None

例如,以下是一个示例函数的定义:

def greet(name):
    "向给定的姓名打招呼,并返回招呼语"
    greeting = f"Hello, {name}!"
    return greeting

在上述示例中,函数名为 greet,它接受一个位置参数 name。文档字符串 "向给定的姓名打招呼,并返回招呼语" 对该函数进行了说明。函数体中的代码用于创建一个招呼语字符串,并将其赋给变量 greeting。然后,使用 return 语句返回 greeting 变量的值。


二、默认参数

def functionname(arg1, arg2=v):

       "函数_文档字符串"

       function_suite

       return [expression]

  • arg2 = v - 默认参数 = 默认值,调用函数时,默认参数的值如果没有传入,则被认为是默认值。
  • 默认参数一定要放在位置参数 后面,不然程序会报错。
1

【例子】

def printinfo(name, age=8):
    print('Name:{0},Age:{1}'.format(name, age))


printinfo('小马')  # Name:小马,Age:8
printinfo('小马', 10)  # Name:小马,Age:10

这段代码定义了一个名为 printinfo 的函数,并对该函数进行了不同的调用。

函数 printinfo 接受两个参数:nameage,其中 age 参数具有默认值 8

在第一次调用时,只传递了一个实参 '小马'printinfo 函数。由于没有提供 age 参数的实参,函数将使用默认值 8。因此,输出结果为 "Name:小马,Age:8"

在第二次调用时,传递了两个实参 '小马'10printinfo 函数。这次提供了 age 参数的实参,函数将使用传递进来的实参值。因此,输出结果为 "Name:小马,Age:10"

2
  • Python 允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

【例子】

def printinfo(name, age):
    print('Name:{0},Age:{1}'.format(name, age))


printinfo(age=8, name='小马')  # Name:小马,Age:8

这段代码定义了一个名为 printinfo 的函数,并对该函数进行了调用,使用关键字参数传递实参。

函数 printinfo 接受两个参数:nameage

在函数的调用中,使用关键字参数的方式指定了参数的值,其中 age=8 表示将值 8 赋给参数 agename='小马' 表示将字符串 '小马' 赋给参数 name

因此,函数调用 printinfo(age=8, name='小马') 将以指定的顺序打印出 "Name:小马,Age:8"

使用关键字参数可以使我们在调用函数时不需要按照特定的顺序来传递实参,而是根据参数名称来传递实参值,提高了代码的可读性和灵活性。


三、可变参数

顾名思义,可变参数就是传入的参数个数是可变的,可以是 0, 1, 2 到任意个,是不定长的参数。

def functionname(arg1, arg2=v, *args):

       "函数_文档字符串"

       function_suite

       return [expression]

  • *args - 可变参数,可以是从零个到任意个,自动组装成元组。
  • 加了星号(*)的变量名会存放所有未命名的变量参数。

【例子】

def printinfo(arg1, *args):
    print(arg1)
    for var in args:
        print(var)


printinfo(10)  # 10
printinfo(70, 60, 50)
# 70
# 60
# 50

这段代码定义了一个名为 printinfo 的函数,并对该函数进行了不同的调用。

函数 printinfo 接受一个位置参数 arg1 和一个可变数量的参数 args,使用了星号 * 来表示该参数可以接收任意数量的实参。

在第一次调用时,只传递了一个实参 10printinfo 函数。因为只有一个实参,所以该实参会被赋给 arg1,而 args 参数为空。因此,输出结果为 10

在第二次调用时,传递了三个实参 70, 60, 50printinfo 函数。其中,70 会被赋给 arg1,而后面的两个实参 6050 会被收集到一个元组中,并赋给 args 参数。然后,通过循环遍历打印出 arg1args 中的每个元素。因此,输出结果为:

70
60
50

可变数量的参数在函数定义中表示为 *args,它允许我们传递任意数量的实参给函数。


四、关键字参数

def functionname(arg1, arg2=v, *args, **kw):

       "函数_文档字符串"

       function_suite

       return [expression]

  • **kw - 关键字参数,可以是从零个到任意个,自动组装成字典。

【例子】

def printinfo(arg1, *args, **kwargs):
    print(arg1)
    print(args)
    print(kwargs)


printinfo(70, 60, 50)
# 70
# (60, 50)
# {}
printinfo(70, 60, 50, a=1, b=2)
# 70
# (60, 50)
# {'a': 1, 'b': 2}

这段代码定义了一个名为 printinfo 的函数,并对该函数进行了不同的调用。

函数 printinfo 接受一个位置参数 arg1,一个可变数量的参数 args(使用了星号 *),以及一个可变数量的关键字参数 kwargs(使用了两个星号 **)。

在第一次调用时,传递了三个实参 70, 60, 50printinfo 函数。其中,70 会被赋给 arg1,而后面的两个实参 6050 会被收集到一个元组中,并赋给 args 参数。关键字参数 kwargs 为空字典。然后,分别打印出 arg1argskwargs 的值。因此,输出结果为:

70
(60, 50)
{}

在第二次调用时,传递了五个实参 70, 60, 50, a=1, b=2printinfo 函数。其中,70 会被赋给 arg1,而后面的两个实参 6050 会被收集到一个元组中,并赋给 args 参数。关键字参数 a=1b=2 会被收集到一个字典中,并赋给 kwargs 参数。然后,分别打印出 arg1argskwargs 的值。因此,输出结果为:

70
(60, 50)
{'a': 1, 'b': 2}

使用可变数量的参数和关键字参数可以使函数更加灵活,允许我们传递不同数量的实参和关键字实参给函数。

「可变参数」和「关键字参数」的同异总结如下:

  • 可变参数允许传入零个到任意个参数,它们在函数调用时自动组装为一个元组 (tuple)。
  • 关键字参数允许传入零个到任意个参数,它们在函数内部自动组装为一个字典 (dict)。

五、命名关键字参数

def functionname(arg1, arg2=v, *args, *, nkw, **kw):

       "函数_文档字符串"

       function_suite

       return [expression]

  • *, nkw - 命名关键字参数,用户想要输入的关键字参数,定义方式是在nkw 前面加个分隔符 *
  • 如果要限制关键字参数的名字,就可以用「命名关键字参数」
  • 使用命名关键字参数时,要特别注意不能缺少参数名。

【例子】

def printinfo(arg1, *, nkw, **kwargs):
    print(arg1)
    print(nkw)
    print(kwargs)


printinfo(70, nkw=10, a=1, b=2)
# 70
# 10
# {'a': 1, 'b': 2}

printinfo(70, 10, a=1, b=2)
# TypeError: printinfo() takes 1 positional argument but 2 were given

这段代码定义了一个名为 printinfo 的函数,并进行了两次调用。

函数 printinfo 接受一个位置参数 arg1,一个命名关键字参数 nkw(通过星号 * 后面添加一个逗号来定义),以及一个可变数量的关键字参数 kwargs(使用了两个星号 **)。

在第一次调用时,传递了四个实参 70, nkw=10, a=1, b=2printinfo 函数。其中,70 会被赋给 arg1,关键字实参 nkw=10 会被赋给 nkw 参数,关键字参数 a=1b=2 会被收集到一个字典中,并赋给 kwargs 参数。然后,分别打印出 arg1nkwkwargs 的值。因此,输出结果为:

70
10
{'a': 1, 'b': 2}

在第二次调用时,传递了三个实参 70, 10, a=1, b=2printinfo 函数。由于 nkw 是一个命名关键字参数,必须通过关键字形式传递给它一个值。但是,在第二次调用中,实参 10 并没有指定给 nkw 的关键字,而是被错误地视为位置参数传递给了 printinfo。因此,会引发 TypeError 并提示函数期望的位置参数数量不匹配。正确的调用方式是使用关键字形式传递给 nkw 参数一个值。如第一次调用所示:

printinfo(70, nkw=10, a=1, b=2)

这样就可以成功执行。

  • 没有写参数名nwk,因此 10 被当成「位置参数」,而原函数只有 1 个位置函数,现在调用了 2 个,因此程序会报错。

六、参数组合

在 Python 中定义函数,可以用位置参数、默认参数、可变参数、命名关键字参数和关键字参数,这 5 种参数中的 4 个都可以一起使用,但是注意,参数定义的顺序必须是:

  • 位置参数、默认参数、可变参数和关键字参数。
  • 位置参数、默认参数、命名关键字参数和关键字参数。

要注意定义可变参数和关键字参数的语法:

  • *args 是可变参数,args 接收的是一个 tuple
  • **kw 是关键字参数,kw 接收的是一个 dict

命名关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。定义命名关键字参数不要忘了写分隔符 *,否则定义的是位置参数。

警告:虽然可以组合多达 5 种参数,但不要同时使用太多的组合,否则函数很难懂。

如有错误欢迎指正,谢谢!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • 函数是组织好的、可重复使用的,用来实现单一或相关联功能的代码段。函数能够提高应用的模块性和代码的重复利用率。Pyt...
    泷汰泱阅读 294评论 0 0
  • 一、函数介绍 什么是函数 请看如下代码:print(" _o...
    辽A丶孙悟空阅读 1,614评论 0 37
  • 为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数 一、定义函数 ~~~ d...
    rookieyu阅读 803评论 0 0
  • 当然在学习Python的道路上肯定会困难,没有好的学习资料,怎么去学习呢?学习Python中有不明白推荐加入交流群...
    01_8a53阅读 449评论 0 0
  • 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。 函数能提高应用的模块性,和代码的重复利用率。你...
    Java丶python攻城狮阅读 454评论 0 1