侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python函数参数操作详解

Python  /  管理员 发布于 7年前   239

本文实例讲述了Python函数参数操作。分享给大家供大家参考,具体如下:

简述

在 Python 中,函数的定义非常简单,满足对应的语法格式要求即可。对于调用者来说,只需关注如何传递正确的参数,以及获取相应的返回值就足够了,无需了解函数的内部实现(除非想学习、跟踪源码)。

话虽如此,但对于函数的定义来说,灵活性非常高。除了常规定义的必选参数以外,还支持默认参数、可变参数、以及关键字参数。这样以来,不但能处理复杂的参数,还可以简化调用者的代码。

形参和实参

不止 Python,几乎所有的编程语言都会涉及两个术语:parameter 和 argument。那么,它们之间究竟有什么区别呢?

parameter 是指函数定义中的参数,而 argument 指的是函数调用时的实际参数。

简略描述:parameter = 形参(formal parameter), argument = 实参(actual parameter)。

例如,定义一个简单的函数:

>>> def greet(param1, param2):...   pass... >>> >>> greet('Hello', 'Python')

其中,param1 和 param2 是函数的形参,而在函数 greet() 被调用时,传入的('Hello' 和 'Python')则是实参。

固定数量参数的函数

到目前为止,关于函数,我们介绍的都是固定数量的参数。来看一个简单的示例:

>>> def greet(say, msg):...   print(say, msg)... >>> >>> greet('Hello', 'Python')Hello Python

这里,函数 greet() 有两个参数,用两个参数调用这个函数,运行得很顺利,不会有任何错误。

倘若,参数的个数不匹配,会发生什么?

>>> greet() # 没有参数...TypeError: greet() missing 2 required positional arguments: 'say' and 'msg'>>> >>> greet('Hi') # 只有一个参数...TypeError: greet() missing 1 required positional argument: 'msg'

显然,解释器会发牢骚。但是,对 Python 来说,要解决这个问题简直是易如反掌,继续往下看!

默认参数

定义函数时,可以使用赋值运算符(=)为参数指定一个默认值。

注意: 如果参数没有默认值,在调用时必需为其指定一个值;如果参数有默认值,那么在调用时值是可选的,如果为其提供了一个值,将会覆盖默认值。

>>> def greet(say, name = 'James', msg = 'I am your biggest fan!'):...   print(say, ',', name, ',', msg)... >>> greet('Hi') # 只提供强制性的参数Hi , James , I am your biggest fan!>>> >>> greet('Hi', 'Kobe') # 给出一个可选参数Hi , Kobe , I am your biggest fan!>>> >>> greet('Hi', 'Kobe', 'I want to challenge you!') # 给出所有参数Hi , Kobe , I want to challenge you!

由于 say 没有默认值,所以必须指定;name、msg 有默认值,所以值是可选的。

函数中的所有参数都可以有默认值,但是,一旦存在一个默认参数,其右侧的所有参数也必须有默认值。也就是说,非默认参数不能在默认参数之后。

例如,将上面的函数定义为:

def greet(name = 'James', say):

就会引发错误:

SyntaxError: non-default argument follows default argument

关键字参数

当使用某些值调用函数时,这些值将根据其位置分配给参数。

例如,在上述函数 greet() 中,当使用 greet('Hi', 'Kobe') 调用它时,'Hi' 被赋值给参数 say,同样地,'Kobe' 被赋值给 name。

Python 允许使用 kwarg = value 格式的关键字参数调用函数:

>>> def greet(say, name = 'James'):...   print(say, ',', name)... >>> >>> greet(say = 'Hi', name = 'Kobe') # 2 个关键字参数Hi , Kobe>>> >>> greet(name = 'Kobe', say = 'Hi') # 2 个关键字参数(次序颠倒)Hi , Kobe>>> >>> greet('Hi', name = 'Kobe') # 位置参数与关键字参数混合使用Hi , Kobe

当以这种方式调用函数时,关键字参数必须在位置参数之后,所有传递的关键字参数都必须与函数接受的某个参数匹配,并且它们的顺序不重要。

例如,像下面这样调用,会引发错误:

>>> greet(name = 'Kobe', 'Hi') # 关键字参数在位置参数之前...SyntaxError: positional argument follows keyword argument>>>>>> greet('Hi', na = 'Kobe') # na 不匹配...TypeError: greet() got an unexpected keyword argument 'na'

可变参数

可变参数也被称为不定长参数,顾名思义,就是传入的参数个数是可变的,可以是任意个(0、1、2 … N)。

要定义可变参数,仅需在参数名之前添加一个星号(*)。在函数内部,这些参数被包装为一个 tuple。

注意: 此 * 非彼 *,不要误认为是 C/C++ 中的指针。

>>> def greet(*names):...   print(names)... >>> >>> greet() # 没有参数,返回空元组()>>>>>> greet('Jordan', 'James', 'Kobe')('Jordan', 'James', 'Kobe')

有时,必须在函数定义中使用位置参数以及可变参数,但位置参数始终必须在可变参数之前。

>>> def greet(say, *names):...   print(say, names)... >>> >>> greet('Hi')Hi ()>>> >>> greet('Hi', 'Jordan', 'James', 'Kobe')Hi ('Jordan', 'James', 'Kobe')

通常情况下,可变参数会出现在形参列表的最后,因为它们会把传递给函数的所有剩余输入参数都收集起来。可变参数之后出现的任何形参都是“强制关键字”参数,这意味着,它们只能被用作关键字参数,而不能是位置参数。

>>> def greet(*names, sep = ','):...   return sep.join(names)... >>> >>> greet('Jordan', 'James', 'Kobe')'Jordan,James,Kobe'>>> >>> greet('Jordan', 'James', 'Kobe', sep = '/') # 被用作关键字参数'Jordan/James/Kobe'>>>>>> greet('Jordan', 'James', 'Kobe', '/') # 被用作位置参数'Jordan,James,Kobe,/'

任意关键字参数

还有一种机制,用于任意数量的关键字参数。为了做到这一点,使用双星号(**):

>>> def greet(**all_star):...   print(all_star)... >>> greet() # 没有参数,返回空字典{}>>> >>> greet(name = 'James', age = 18){'name': 'James', 'age': 18}

当最后一个形式为 **msgs 的形参出现时,它将收到一个字典,其中包含所有关键字参数,除了与形参对应的关键字参数之外。还可以与 *names 的形参相结合(*names 必须出现在 **msgs 之前)。

例如,定义一个这样的函数:

>>> def greet(say, *names, **msgs):...   print('--', say)...   for name in names:...     print(name)...   print('-' * 40)...   keys = sorted(msgs.keys())...   for key in keys:...     print(key, ':', msgs[key])... >>> >>> greet('Hi', 'Jordan', 'James', 'Kobe', msg = 'I want to challenge you!', challenger = 'Waleon')-- HiJordanJamesKobe----------------------------------------challenger : Waleonmsg : I want to challenge you!

注意: 在打印内容之前,通过对 msgs 字典的 keys() 方法的结果进行排序来创建关键字参数名称列表。如果没有这样做,则打印参数的顺序是未定义的。

对参数进行解包

正如“可变参数”那样,也可在函数调用中使用 * 操作符。只不过在这种情况下,与在函数定义中 * 的语义相反,参数将被解包而不是打包。

>>> def greet(name, age):...   print(name, age)... >>> >>> t = ('James', 18)>>> greet(*t)James 18

还有一种方式,几乎没有必要提到,这里也罗嗦一下:

>>> greet(t[0], t[1])James 18

与解包相比,这种调用方式显然不舒适。另外,在一般情况下,调用 greet(t[0], t[1]) 几乎是徒劳的,因为长度是未知的。“未知”的意思是:长度只在运行时才知道,而不是在编写脚本时就知道。

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

>>> def greet(name, age = 18):...   print(name, age)... >>> >>> d = {'name':'James', 'age':32}>>> greet(**d)James 32

Python获取函数参数个数:

Python2.7写法:

# -*- coding:utf-8 -*-#! python2def abc(a,b,c):  print a,byy=abc.func_code.co_argcountprint yy

输出结果为

3

python3.6写法

# -*- coding:utf-8 -*-#! python3def abc(a,b,c):  print(a,b)a=abc.__code__.co_argcountprint(a)

输出结果为

3

使用场景:

比如在REST规范的代码中,request数据格式检验,判断携带参数个数是否符合该函数所需参数的个数,不是就可以return error了

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python函数使用技巧总结》、《Python数学运算技巧总结》、《Python数据结构与算法教程》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。


  • 上一条:
    python开启摄像头以及深度学习实现目标检测方法
    下一条:
    利用python打开摄像头及颜色检测方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客