Python函数参数详解

形参与实参

什么是形参


  在定义函数阶段定义的参数称之为形式参数,简称形参,相当于变量名。

什么是实参


  在调用函数阶段传入的值称为实际参数,简称实参。相当于"变量值"的内存地址。(Ps:Python中的所有传值都是传递的内存地址,因此Python中的传值也被称为引用传值。)

实参与形参的关系


   1.在调用阶段,实参("变量值的内存地址引用")会绑定给形参("变量名")

   2.这种绑定关系只能在函数体内使用

   3.实参与形参的绑定关系在函数调用时生效,函数调用结束后解除绑定关

形参定义方式

位置形参


  在函数定义阶段,按照从左到右的顺序直接定义的"变量名"被称为位置形参,它的特点是必须被传值,多一个少一个也不行

默认形参


  默认形参的值是在函数定义阶段就被赋予的,准确的说是赋予形参了一个默认的值的内存地址。当调用时可以不对该形参进行传值,如不对该形参进行传值则使用默认的值,反之则使用传入的实参值,需要注意在定义时默认形参必须放在位置形参后面,否则会抛出异常

实参传值方式

位置传参


  上面一直在使用位置传参的方式,在函数调用阶段,按照从左至右的顺序依次传入值的方式被称为位置传参,特点是按照实参摆放的顺序与形参一一对应进行传值。来看一段错误示范:

关键字传参


  在函数调用阶段,按照key=value的形式传入值的方式被称为关键字传参,可以打破顺序为形参进行传值。注意:若使用关键字传参需注意必须跟在位置传参的后面。(也是个人比较推崇的一种传值方式)。

多参函数的形参与实参传值

位置传参与 *


  *是一种语法,args是一种约定俗称。如果定义一个函数时不知道使用者要用位置传参的方式传入多少个实参,可使用*args来进行接收所有多余的被传入的实参,这些多余的被传入实参会被打包成元组类型。args只是形参名,但是按照约定俗称如果要接收多个实参的形参名一般命名为args

# ==== *args 的使用 ====

def func(x,y,*args):
print("x -->",x)
print("y -->",y)
print("args -->",args)

func(1,2,3,4,5,"",[7,8,9]) # 实参 1 和 2 会根据位置传参依次被形参x,y所接收(内存地址)。剩下的所有通过位置传参的实参全部被args所接收。

# ==== 执行结果 ====

"""
x --> 1
y --> 2
args --> (3, 4, 5, '6', [7, 8, 9])
"""

关键字传参与 **


  **也是一种语法。kwargs则是后面形参名的约定俗称。如果定义一个函数时不知道使用者要用关键字传参的方式传入多少个实参,可使用**kwargs来进行接收所有多余的被传入的实参,这些多余的被传入实参会被打包成字典类型。

# # ==== **kwargs 的使用 ====

def func(name,age,**kwargs):
print("name -->",name)
print("age -->",age)
print("kwargs -->",kwargs)

func("yunya",18,gender="male",height="1.92",body_weight="180Kg") # 实参yuya,18通过位置传参会被name和age所接受(内存地址),剩下的所有关键字传参的实参全部被kwargs所接收。

# ==== 执行结果 ====

"""
name --> yunya
age --> 18
kwargs --> {'gender': 'male', 'height': '1.92', 'body_weight': '180Kg'}
"""

实参中 * 的使用


  *可以用在实参中,实参中带*,先将*后面的值(一般为容器类型,不包含字典类型)拆分为实参后再以位置传值的方式进行传入

# ==== 实参中 * 的使用 ====

def func(x,y,z):
print("x --->",x)
print("y --->",y)
print("z --->",z)

func(*["a","b","c"])

# ==== 执行结果 ====

"""
x ---> a
y ---> b
z ---> c
"""

实参中 ** 的使用


  **也可以用在实参中,实参中带**,先将**后面的值(必须为字典类型)拆分为key=value的形式后再以关键字传值的方式进行传入

# ==== 实参中 ** 的使用 ====

def func(x,y,z):
print("x --->",x)
print("y --->",y)
print("z --->",z)

func(**{"x":1,"y":2,"z":3})

# ==== 执行结果 ====

"""
x ---> 1
y ---> 2
z ---> 3
"""

*args 与 **kwargs的组合使用


  其实关于实参传值的方式就两种,一种是位置传参,一种是关键字传参。所以一个函数如果定义了*args**kwargs后则代表它能够接受足够多的参数。需要注意的是*args必须定义在**kwrags之前,否则会抛出异常。

# ==== *args 与 **kwargs 的组合使用 ====

def wrapper(*args, **kwargs):
print(args) # (1, 2, 3)
print(kwargs) # {'name': 'Yunya', 'age': 18}


wrapper(1, 2, 3, name="Yunya", age=18)

扩展:命名关键字参数

  我们可以指定某些形参的传值方式必须为关键字传参。那么这些被规定死了传值方式的形参则被称为命名关键字参数,它同位置形参,默认形参是同一级别的。我们先来看一下下面的代码:

  我们来看一下默认形参的报错提示是什么:

  由于命名关键字参数的应用场景十分少见,Pycharm也会在某些时候进行一些错误的提示:

扩展:定义形参顺序及传入实参顺序

  注意:以下场景在实际开发中不可能遇到。但是这里还是做一个补充。

扩展:函数嵌套与*和**传参

  这里要提前说一下,下面这个实例是为了给装饰器打基础,装饰器算是Python基础里比较难的一个点。它包含函数嵌套使用与***的多重传参,这里不说那么多。直接上个代码图,看懂了就可以关闭本页面了。

# ==== 函数嵌套与*和**的组合使用 ====

def func(x, y, z):
print(x, y, z) # 1 v1 v2


def wrapper(*args, **kwargs):
func(*args, **kwargs) # 实参用 * 和 ** 。拆分开, * 是位置传值,**是关键字传值.
# args (1) kwargs {"y":"v1","z":"v2"} 拆分成 ---> func(1,y="v1",z="v2") 最终传入样式


wrapper(1, y="v1", z="v2")

扩展:传参类型提示

# ==== 传参类型提示 ====

def func(x:str,y:int,z:list)->"""返回str类型""":
return "hello,world"

print(func.__annotations__)

"""
Python3.5之后新增了类型提示功能。在输入参数的时候会显示一定的提示,
注意:这只是一种提示,并不会真正限制你传参时的数据类型。
"""

# ==== 执行结果 ====

"""
{'x': <class 'str'>, 'y': <class 'int'>, 'z': <class 'list'>, 'return': '返回str类型'}
"""

Python函数参数详解的更多相关文章

  1. PHP date函数参数详解

    PHP date函数参数详解 作者: 字体:[增加 减小] 类型:转载       time()在PHP中是得到一个数字,这个数字表示从1970-01-01到现在共走了多少秒,很奇怪吧 不过这样方便计 ...

  2. Go语言Slice作为函数参数详解

    Go语言Slice作为函数参数详解 前言 首先要明确Go语言中实质只有值传递,引用传递和指针传递是相对于参数类型来说. 个人认为上诉的结论不对,把引用类型看做对指针的封装,一般封装为结构体,结构体是值 ...

  3. 【集成学习】sklearn中xgboot模块中fit函数参数详解(fit model for train data)

    参数解释,后续补上. # -*- coding: utf-8 -*- """ ############################################## ...

  4. Python包管理工具setuptools之setup函数参数详解

    **********************************************************对所学内容的简单汇总******************************** ...

  5. Python print函数参数详解

    官方文档 print(…)    print(value, …, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)    Prints the valu ...

  6. Python3学习笔记(十一):函数参数详解

    一.位置参数 根据参数的位置来传递参数,调用函数时,传递的参数顺序和个数必须和定义时完全一致 # 定义函数 def man(name, age): print("My name is %s, ...

  7. Python学习教程(learning Python)--2.3.2 Python函数实参详解

    本节主要讨论函数调用时参数的实参问题. 1. 实参赋值顺序和型参定义顺序一一对应 Python在调用哪个子函数时,如果型参为多个,一般实参的排布顺序和型参顺序保持一致,即一一对应.我们以下面的代码为例 ...

  8. CGBitmapContextCreate函数参数详解

    函数原型: CGContextRef CGBitmapContextCreate ( void *data, size_t width, size_t height, size_t bitsPerCo ...

  9. PHP中date函数参数详解

    date函数输出当前的时间echo date('Y-m-d H:i:s', time()); // 格式:xxxx-xx-xx xx:xx:xx 第一个参数的格式分别表示: a - "am& ...

随机推荐

  1. Ubuntu18.04兼容Python2.7、Python3.6、Python3.8以及pip、pip2、pip3问题

    Ubuntu18.04兼容Python2.7.Python3.6.Python3.8以及pip.pip2.pip3问题 此为记录我重装Ubuntu后安装Python的过程 安装Python3.8 目前 ...

  2. Rocket - devices - CLINT

    https://mp.weixin.qq.com/s/4LfZZDKCTQhiKIUjvbDKEg 简单介绍CLINT的实现. 1. 概述 CLINT即是Core Local Interrupter的 ...

  3. jchdl - RTL实例 - AndAnd

    https://mp.weixin.qq.com/s/JhUB3M1WhjAyUrN1HPIPTA   AndAnd是三输入与门模块,输出为相与的结果.   参考链接 https://github.c ...

  4. vue-组件化-插槽(slot)

    理解 Vue组件化中,当我们在设计一个组件的时候,可能会保留一部分,让使用者自定义的内容,比如: 导航栏组件中,右上角的分享按钮,左上角做菜单按钮 弹出框组件中,弹出框的提示内容等 ... 在这种场景 ...

  5. Java实现 LeetCode 105 从前序与中序遍历序列构造二叉树

    105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中 ...

  6. Java实现 LeetCode 6 Z字形变换

    6. Z 字形变换 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: L ...

  7. Java实现 蓝桥杯 算法提高 最大值路径

    试题 算法提高 最大值路径 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 刷微博,编程序.如下图所示,@北京发布 提出了如下"头脑震荡"问题.对此问题做一般化描 ...

  8. TZOJ 公交车

    描述 公交车在一条笔直的道路(道路宽度忽略,设为X轴)上行驶,按顺序路上有若干个站点(X坐标值),crq的家也在道路旁某个位置h(X坐标值),现在crq想知道哪个站点下车离家最近. 输入 输入数据的第 ...

  9. Java学习的一般过程

    伴随着科学技术的不断发展,世界开始走向信息化.网络化.大数据化.自然而然,计算机专业变得十分热门.尽管如此,计算机专业人才对社会来说仍然是供不应求,当然,这里指的是高层次技术人才.因此,对于我们这些占 ...

  10. ffmpeg m3u8生成 剪辑及格式转换

    使用 ffmpeg 工具, 生成 m3u8 文件 ffmpeg -re -i 03.ts -c copy -f hls -hls_base_url /Users/admin/Downloads/dow ...