Python3函数参数详解 - vip共享吧
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们


导航菜单
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们
Python

Python3函数参数详解

2024/9/6 韩俊  Python教程 472 0

定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了,对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解。

Python 的函数定义非常简单,但灵活度却非常大,除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码,本节我们就来学习函数的各种参数定义。

位置参数

位置参数也叫必传参数,也就是函数的实参的个数和位置必须和形参的个数和位置一致。说明:我们把函数定义时的参数叫做形参,调用函数时给的参数叫做实参。

def myfunc(name, age):
    print(name)
    print(age)

myfunc("ruhua", 18)                # 实参 "ruhua" 对应形参 name,实参 18 对应形参 age
myfunc("ruhua", "zhaoritian", 18)  # 错误,实参和形参的参数个数不匹配

Python 是动态语言,在定义函数的时候没法给形参定义类型,所以我们需要对调用的函数参数类型说明要清楚,不然会得到错误的逻辑结果。

def myfunc(name, age):
    print(name)
    print(age)

myfunc(18, "ruhua")  # 实参 18 对应形参形参 name,实参 "ruhua" 对应形参 age

默认参数

在函数定义时,如果给某个参数提供一个默认值,这个参数就变成了默认参数,不再是位置参数了。在调用函数的时候,我们可以给默认参数传递一个自定义的值,也可以使用默认值。

def girlsschool(name, sex="f"):
    print(name)
    print(sex)

girlsschool("wanghuahua")
girlsschool("ruhua", "m")

有多个默认参数时,调用的时候,既可以按顺序提供默认参数,也可以不按顺序提供部分默认参数,当不按顺序提供部分默认参数时,需要把参数名写上。

def girlsschool(name, age=18, sex="f"):
    print(name)
    print(age)
    print(sex)

girlsschool("ruhua", sex="m", age=17)

使用默认参数时要确保位置参数在前,默认参数在后,否则 Python 的解释器会报错。其实大家可以思考一下原因(如果默认参数在位置参数前面,由于位置参数是按次序接收实参的,所有默认参数在实参中必须给出,这样的话默认参数就没法默认了)。

def girlsschool(age=18, name):   # 函数参数定义错误
    pass

def _girlsschool(name, age=18):  # ok
    pass

默认参数详解

从一个例子说起,对于以下代码,我们预期的结果是:调用 func(),L 的值是 [2],再次调用 func(),L 的值还是 [2],而结果是:[2],[2, 2]。

def func(L=[]):
    L.append(2)
    print(L)

func()
func()

我们都知道函数的默认参数也是局部变量,但 Python 的函数在第一次使用默认参数的时候,该默认参数指向的内存就确定了,这与其他语言不同(在其他语言中,默认参数每次调用都要重新分配内存),我们打印出默认参数 L 的 id 发现两次调用都是一样。

def func(L=[]):
    print(id(L))
    L.append(2)
    print(L)

func()
func()

我们通过在函数体内定义一个局部变量,来看下 Python 解释器的行为,我们发现两次调用 L 指向的内存确实不是一个(第一次结果为 [2], 第二次结果为 [2]),但是打印出的内存地址确是一样的。

def func():
    L = []
    print(id(L))
    L.append(2)
    print(L)

func()
func()

导致上面结果的原因是内存分配机制是一样的,我们可以通过下面的代码来证明,通过下面的代码,我们发现第一次调用 func 函数中 L 的 id 和 mylist 的 id 是一样的,和第二次调用 func 函数中 L 的 id 并不一样。

def func():
    L = []
    print(id(L))
    L.append(2)
    print(L)

func()
mylist = []
print(id(mylist))
func()

对于默认参数是变量的情况出现的坑,我们可以通过修改默认参数的值为常量来避免。

def func(L=None):
    if not isinstance(L, list):
        L = []
    L.append(2)
    print(L)

func()
func()

为什么要设计 str,None 这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改, 这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁, 同时读一点问题都没有,所以我们在编写程序时,如果默认参数可以设计一个不变对象,那就尽量设计成不变对象。

可变参数

在 Python 函数中,实参个数可以是不固定的,就是我们调用函数时传入的实参个数是可变的(可以是任意个数,还可以是 0 个),可变参数的形参要写成 *变量名 的形式。

def func(*arg):
    print(arg)

func()
func(1)
func(1, 2, 3)

对于定义可变参数的函数,我们调用函数时,无论传入的实参参数类型是什么,个数是多少个(包括 0 个), Python 解释器都会把对应的实参组成一个 tuple 传给形参。

def func(*arg):
    print(arg)

func()                  # 0 个实参,arg 被组成 ()
func(1, 2)              # 2 个实参,arg 被组成 (1, 2)
func("hello")           # 1 个实参,arg 被组成 ("hello",)
func(1, [1, 2])         # 2 个实参,arg 被组成 (1, [1, 2])
func((1, 2))            # 1 个实参,arg 被组成 ((1, 2),)
func({1: 2})            # 1 个实参,arg 被组成 ({1: 2},)

如果传入的实参类型是集合(str, list, tuple, dict, set), Python 允许在实参前面加一个 * 号,此时 Python 解释器则会把实参中的所有成员(字典是键)展开。

def func(*arg):
    print(arg)

# 解释器会把 *"hello" 展开为 'h','e','l','l','o',实参变为('h','e','l','l','o')
func(*"hello")

# 解释器会把 *[1, 2] 展开为 1, 2,实参变为(1, 1, 2)
func(1, *[1, 2])

# 解释器会把 *(1, 2) 展开为 1, 2,实参变为(1, 2)
func(*(1, 2))

# 解释器会把 *{1: "1", 2: "2"} 展开为 1, 2 ,实参变为(1, 2)
func(*{1: "1", 2: "2"})

如果可变参数在位置参数或默认参数的前面,就变成了命名关键字参数(下面学习)。

def girlsschool(*sex, name):     # 命名关键字参数(下面讲解定义)
    pass

def _girlsschool(*sex, age=18):  # 命名关键字参数(下面讲解定义)
    pass

def _girlsschool(*sex, age, name="ruhua"):  # 命名关键字参数(下面讲解定义)
    pass

def _girlsschool(*sex, age=18, name):  # 命名关键字参数(下面讲解定义)
    pass

def _girlsschool(name, *sex, age=18):  # 命名关键字参数(下面讲解定义)
    pass

def _girlsschool(name="ruhua", *sex, age):  # 命名关键字参数(下面讲解定义)
    pass

关键字参数

可变参数允许你传入 0 个或任意个参数,我们知道这些可变参数在函数调用时自动组装为一个 tuple。而关键字参数允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个 dict。

def func(**arg):
    print(arg)

func()
func(name="ruhua", age=18)

如果传入的实参类型是 dict,Python 允许在实参前面加一个 ** 号,此时 Python 解释器则会把字典类型的实参转为 key=value 的形式。

def func(**arg):
    print(arg)

stuents_dict = {"name": "ruhua", "age": 18}

# 解释器会把 **stuents_dict 转为 name="ruhua", age=18,最后的实参为(name="ruhua", age=18)
func(**stuents_dict)

# 解释器会把 **stuents_dict 转为 name="ruhua", age=18,最后的实参为(sex="f", name="ruhua", age=18)
func(sex="f", **stuents_dict)

要确保关键字参数在可变参数和默认参数和位置参数的后面,否则 Python 的解释器会报错。

def girlsschool(name, age=18, **beauty, *sex):   # 函数参数定义错误
    pass

def _girlsschool(name, age=18, *sex, **beauty):  # ok
    pass

命名关键字参数


命名关键字参数是在 Python 3 中新增加的一种语法,它和关键字参数 **kw 不同,命名关键字参数需要一个特殊分隔符 * ,* 后面的参数被视为命名关键字参数。例如,只接收 sex 和 lover 作为关键字参数,这种方式定义的函数如下。

def Human(name, age, *, sex, lover):
    print(name, age, sex, lover)

Human('ruhua', 18, sex='f', lover='tangbohu') # ruhua 18 f tangbohu

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符 * 了。

def Human(name, age, *args, sex, lover):
    print(name, age, args, sex, lover)

Human('ruhua', 18, sex='f', lover='tangbohu') # ruhua 18 () f tangbohu

命名关键字参数必须传入参数名,这和位置参数不同,如果没有传入参数名,Python 解释器则报异常。

def Human(name, age, *, sex, lover):
    print(name, age, sex, lover)

Human('ruhua', 18, 'f', 'tangbohu')  # 必须要指定参数名 sex 和 lover

命名关键字参数可以有默认值,从而简化调用,给命名关键字参数设置默认值和给默认参数设置默认值的规则不一样,命名关键字参数不限制默认值的顺序。

def Human(name, age, *, sex, lover="tangbohu"):
    print(name, age, sex, lover)

Human('ruhua', 18, sex='f') # ruhua 18 f tangbohu

##################我是分割线##################
def Human(name, age, *, sex="f", lover):
    print(name, age, sex, lover)

Human('ruhua', 18, lover='tangbohu') # ruhua 18 f tangbohu

各种类型参数组合使用

在 Python 中定义函数,可以用位置参数,默认参数,可变参数和关键字参数,这 4 种参数都可以一起使用,或者只用其中某些,但是请大家养成一个好习惯,尽量不要使用命名关键字参数,参数定义的顺序最好按照:必选参数,默认参数,可变参数和关键字参数的写法。

def func(a, b="ok", *c, **d):
    pass

参数组合混用的时候,如果形参的默认参数后面有可变参数,传给默认参数的实参最好不要指定名称。

def girlsschool(age=18, *sex):
    print(age)
    print(sex)

girlsschool(age=19, "f")   # 错误

本节重要知识点

Python 中默认参数的实现机制。

可变参数和关键字参数的实现机制

参数组合混用注意事项。

点赞:0 分享

上一篇
Python3匿名函数
下一篇
Python3函数自定义和调用
作者头像 作者名称 作者性别
韩俊

热门推荐

1 Python中urllib模块详解
2 Python中xml文件处理
3 Python3切片
4 Python中itertools模块如何使用
5 Python文件处理和输入输出(IO)
6 Python3的set类型

评论列表

取消回复

    •  
      Login

      韩俊

      趁你现在还有时间,尽你自己最大的努力,努力做成你最想做的那件事,成为你最想成为的那种人,过着你最想过的那种生活。这个世界永远比你想的要更精彩,不要败给生活。

      退出登陆
      • 10076文章
      • 455评论
      • 80微语
  • 广告赞助

  • 二零二五年06月
    一二三四五六日
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
  • 分类

    • 网站模板源码
    • IT技术笔记
    • 好资源分享
    • 共享网络资源
  • 最新文章

      • 幼儿端午祝福语简短句
        • 端午简短祝福语送家人
          • 端午文案祝福语简短励志
            • 经典的黄句子
              • 经典黄色搞笑句子
                • 迷雾通:免费使用的VPN软件
                  • 任推邦:打造你的赚钱新途径!
                    • 任推邦是正规平台吗?任推邦邀请码多少?
  • 热门文章

    • 酷狗音乐VIP账号 酷狗音乐会员账号共享2017.01.29更新
    • 芒果tv vip会员账号 芒果tv会员账号共享2017.01.29更新
    • 爱奇艺vip账号 爱奇艺/PPS会员账号共享2016.12.12更新
    • 优酷/土豆vip会员账号 优酷会员账号共享2017.01.29更新
    • 活动:免费获得爱奇艺VIP/PPS会员账号50天以上的使用权!
    • 酷我音乐VIP账号 酷我音乐会员账号共享2016.12.31更新
    • 暴风影音会员账号 暴风影音会员账号共享2016.12.31更新
    • m1905会员账号 m1905会员账号共享2016.10.21更新
  • 最新评论

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/10.jpg

      你丫的 文章写得太好了 支持下!![F3...

    • https://www.vipshare8.com/content/templates/meta/Static/images/avatar.jpg

      很棒!刚在某网站看到这个,很欣赏,可惜下...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3861064027

      呃呃呃 oooo

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了111:根据激活的时间有一年的有效期!

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=792480561

      到2025就到期了吗?

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      [blockquote]打卡时间:16:...

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/7.jpg

      俊哥,想借用迅雷一用!但需要手机验证!看...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3293901900

      感谢大大的分享

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了好奥v:如果没有解析成功,可以切换接口...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=131241242441

      现在视频解析网站怎么用不了啦?

  • 网站统计 I 当前在线:283人

    • 本站管理:1位
    • 用户总数:591位
    • 置顶文章:2篇
    • 日志总数:10076篇
    • 微语总数:80条
    • 评论总数:455条
    • 标签总数:83条
    • 页面总数:8页
    • 分类总数:14个
    • 链接总数:16条
    • 运行天数:3699天
    • 最后更新:5月26日
    • 登录
    • 注册
    • 找回
    Copyright © 2025vip共享吧网站地图 网站备案豫ICP备19004194号-1

    免责声明:本站资源仅供用于学习和交流,本站部分素材内容来源于网络,如有侵权/投稿等,请及时联系站长.

    • 首页
    • 秒懂百科 秒懂百科
    • 搜索
    • 史上今日

    大家都在搜

    • 优酷vip账号共享
    • 搜狐视频会员账号
    • 酷狗VIP账号
    • 聊天app
    • swoole
    • 全民娱乐
    • MySql
    • 阴阳师
    • 威客平台
    • 飞卢小说会员账号
    • seo
    • m1905会员账号共享
    • 秒懂百科
    • 芒果tv会员
    • 掌阅vip账号共享
    • 掌阅会员账号
    • 
    • 