Python——第三章:函数的定义
函数的定义:
对某一个特定的功能或者代码块进行封装. 在需要使用该功能的时候直接调用即可
格式:
def 函数的名字():
    被封装的功能或者代码块->函数体调用:
函数的名字()使用函数的好处:
把多次重复调用的代码打包封装
- 让程序更加简洁直观,代码更加合理
- 方便一句话调用代码
- 方便一次性完成全局修改
def xia_ban():  # 定义函数,每天下班都要做重复的事
    print("1. 打车")
    print("2. 去菜市场")
    print("3. 讨价还价")
    print("4. 回家")
    print("5. 做饭")
#每天都做的重复的事+不同的事
xia_ban()
print("哄哄孩子")
xia_ban()
print("冲洗马桶")
xia_ban()
print("打打游戏")函数的参数: 可以在函数调用的时候. 给函数传递一些信息
参数分类:
- 形参, 在函数定义的时候. 需要准备一些变量来接收信息- 位置参数, 按照位置一个一个的去声明变量
- 默认值参数, 在函数声明的时候给变量一个默认值, 如果实参不传递信息. 此时默认值生效, 否则就不生效
- 动态传参.
- 位置动态传参:*args
- 关键字动态传参:**kwargs
 
- 位置动态传参:
- *混合使用时的位置顺序: 位置参数 > *args > 默认值参数 > **kwargs
 
- 实参, 实际在调用的时候传递的信息- 位置参数. 按照位置进行传递参数
- 关键字参数. 按照参数的名字进行传递参数
- 混合参数.
- 顺序: 位置参数放前面, 关键字参数放后面 -> 否则报错! 官方不让这么干
- 实参在执行的时候. 必须要保障所有形参都有数据
 
骂人也需要参数:
- 骂谁?
- 骂到什么程度?
def maren(ren, level):  # 形参
    print("1. 怒目而视", ren)
    print("2. 严重交涉", ren)
    if level > 99:
        print("3. 死不要脸")
    else:
        print("3. 你愁啥")
    print("4. 骂完收工")
maren("破键盘", 188)  # 实参 -> 在调用函数的时候,才能明确之前的形参ren和level
maren("破鼠标", 10)
maren("破电脑", 999)请用函数编写一个计算器, 能计算 + - * / 四则运算
def jisuan(a, opt, b):
    if opt == "+":
        print(a + b)
    elif opt == '-':
        print(a - b)
    elif opt == '*':
        print(a * b)
    elif opt == '/':
        print(a / b)
    else:
        print("错误")
jisuan(999, "+", 666)
jisuan(999, "-", 666)
jisuan(999, "*", 666)
jisuan(999, "/", 666)
jisuan(999, "^&*", 666)实参分类:
- 位置参数. 按照位置进行传递参数
- 关键字参数. 按照参数的名字进行传递参数
- 混合参数.(一定要先位置参数,再关键字参数)
def chi(zhu, fu, tang, tian):
    print(zhu, fu, tang, tian)
chi("大米饭", "西红柿炒鸡蛋", "紫菜蛋花汤", "哈根达斯")    #位置参数
chi(zhu="小米饭", tang="胡辣汤", fu="韭菜炒大腰子", tian="老中街冰棍")    #关键字参数
chi("小米饭", "胡辣汤", tang="韭菜炒大腰子", tian="老中街冰棍")    #先位置+后关键字参数chi() 实参在执行的时候,必须要保障所有形参有被赋值数据。这就类似open用法,在调用时open("xxxx", mode="xx", encoding="xxx")所有参数都要被标明。
形参分类:
- 位置参数(Positional Arguments): - 位置参数是最普通的参数类型,它们按照在函数定义中的顺序接收传递的值。
- 例如:def example_function(arg1, arg2):
 
- 关键字参数(Keyword Arguments): - 关键字参数通过指定参数名来传递值,与位置无关。可以在函数调用中的任何位置指定关键字参数,不需要按照函数定义的顺序。例如:example_function(arg1=value1, arg2=value2)
- 关键字参数是在函数调用时,通过指定参数名来传递值的一种方式。
 
- 关键字参数通过指定参数名来传递值,与位置无关。可以在函数调用中的任何位置指定关键字参数,不需要按照函数定义的顺序。例如:
- 默认值参数(Default Arguments): - 默认参数在函数定义时给定默认值,如果在函数调用时没有提供相应参数的值,则使用默认值。例如:def example_function(arg1, arg2=0):
 
- 默认参数在函数定义时给定默认值,如果在函数调用时没有提供相应参数的值,则使用默认值。例如:
- 动态参数(Arbitrary Argument Lists): - 动态参数使用 *和**来允许函数接受任意数量的位置参数和关键字参数。
- 动态位置参数*args表示接受任意数量的位置参数def func(a, b, c, *args):
- 任意位置形参在执行后,会被包装成元组存储下来。
- *args本身不能被关键字赋值,只能位置赋值。
- 动态关键字参数**kwargs表示接受任意数量的关键字参数。def func(**kwargs):
- 任意数量的关键字形参在执行后,会被包装成字典存储下来。
- **kwargs不能被位置赋值,只能被字典赋值
- 因此,万能的赋值写法是:def example_function(*args, **kwargs):
 
- 动态参数使用 
- 命名关键字参数(Keyword-Only Arguments): - 命名关键字参数是一种限定参数必须通过参数名传递的方式,而不允许通过位置传递的参数。
- 在函数定义中,通过在位置参数后使用 *来标识,表示之后的参数必须以关键字的形式传递(位置不限)。例如:kwarg1和kwarg2必须通过关键字传递,而不允许通过位置传递。def example_function(arg1, *, kwarg1, kwarg2):
 print(arg1, kwarg1, kwarg2) example_function("value1", kwarg2="value2", kwarg1="value3")
- 前面出现了*args,后面的所有参数都需要用关键字赋值def func(a, b, *args, c, x, y, z **kwargs):这里c,x,y,z都只能被关键字赋值。因为*args中也有*。但是*args的值是还是位置赋值,*args本身不能被关键字赋值。
 
位置形参、赋值
定义三个形参name, age, gender并且将gender默认赋值为"男",因此genderl可以不赋值,自动使用默认值。
def luru(name, age, gender="男"):
    print(name, age, gender)
luru("张三", 18)
luru("李四", 28)
luru("王二麻子", 38)
luru("吴老二", 14)
luru("赵敏", 12, "女")
luru("周芷若", 11, "女")动态形参
任意位置形参
对于动态传参,可以使用*表示,任意位置传参,位置参数可以是任意的数量。接收到的值会被统一放在一个元组里面。
这里注意,如果是1个参数,后门还有个空,由于 food 是一个带有星号的参数,传递给它的值会被放在一个元组中。即便你只传递一个参数,也会被包装成元组。因此,结果是 ('大米饭',),其中的逗号表示这是一个包含一个元素的元组。
("大米饭")只表示一个字符串,而不是元组
def chi(*food):  # * 表示位置参数的动态传参, *接收到的值会被统一放在一个元组里面
    print(food)
chi('大米饭', "烧茄子", '紫菜蛋花汤', "哈根达斯")
chi("大米饭")
chi("大米饭", "烧茄子")
chi("大米饭", "紫菜蛋花汤")
chi("大米饭", "紫菜蛋花汤", "紫菜蛋花汤")
#运行结果
('大米饭', '烧茄子', '紫菜蛋花汤', '哈根达斯')
('大米饭',)
('大米饭', '烧茄子')
('大米饭', '紫菜蛋花汤')
('大米饭', '紫菜蛋花汤', '紫菜蛋花汤')任意关键字形参
对于动态传参,可以使用**表示任意关键字传参,关键字参数可以是任意数量。接收到的所有参数都会被处理成字典
def chi(**food):  # ** 表示接收关键字的动态传参, 接收到的所有参数都会被处理成字典
    print(food)
chi(fu="木须柿子", zhu="小米饭")混合形参的排序
形参可以混合出现。要如何排序?才能让有默认值的形参生效。
- *首先应满足:位置参数放前面, 关键字参数放后面 -> 否则报错! 官方不让这么干 -> 1.位置参数 > 2.位置动态传参 > 3.关键字动态传参
- *然后我们应该思考: 带默认值的参数应该放在什么位置?
错误的混合形参顺序:
1.位置参数 > 2.默认值参数 > 3.位置动态参数 > 4.关键字动态参数 (错误举例)
def func(a, b, c="哈哈", *args, **kwargs):
    print(a, b, c, args, kwargs)
func(1,2,3,4,5,6 c="呵呵", hello=456, hahalou =654)
#运行结果报错,c被多次赋值
    func(1,2,3,4,5,6 c="呵呵", hello=456, hahalou =654)
TypeError: func() got multiple values for argument 'c'这种情况是因为,3首先因为位置关系,会被传给c。4 5 6会被传到*args中。然后c="呵呵"又一次被赋值给c,造成重复赋值报错。
这种时候,不能带关键字赋值给c,只能靠位置将3赋值给c,因此这种模式的写法是有限制和问题的。
def func(a, b, c="哈哈", *args, **kwargs):
    print(a, b, c, args, kwargs)
func(1,2,3,4,5,6, hello=456, hahalou =654)    #没有
#运行结果
1 2 3 (4, 5, 6) {'hello': 456, 'hahalou': 654}正确的混合形参顺序:
1.位置参数 > 2.位置动态传参 > 3.默认值参数 > 4.关键字动态传参 (此时,形参中有默认值的参数只能通过关键字传参修改,且位置受不限制)
运行func()时,有关键字c="呵呵"传参,且放在的hello和hahalou中间也不受影响
def func(a, b, *args, c="哈哈", **kwargs):
    print(a, b, c, args, kwargs)
func(1,2,3,4,5,6, hello=456, c="呵呵", hahalou =654)
#运行结果
1 2 呵呵 (3, 4, 5, 6) {'hello': 456, 'hahalou': 654}运行func()时,即使没有关键字c=""传参,会使用默认值c="哈哈"
def func(a, b, *args, c="哈哈", **kwargs):
    print(a, b, c, args, kwargs)
func(1,2,3,4,5,6, hello=456, hahalou =654)
#运行结果
1 2 哈哈 (3, 4, 5, 6) {'hello': 456, 'hahalou': 654}在Python中,完整的形参排序规则是:
- 位置参数(Positional Arguments)
- 默认值参数——位置(Default Arguments)默认值参数如果放在这里,最好仅使用位置赋值。若执意使用关键字赋值的方式,可能会出现重复赋值的情况。若想使用关键字赋值更适合放在位置5.关键字——默认值参数
- 动态位置参数(Arbitrary Argument Lists) *args
- 关键字参数(Keyword-Only Arguments) *, kwarg1,kwarg2
- 默认值参数——关键字 *, kwarg2="default_kwarg"这个位置只可以通过关键字赋值,就无法使用位置赋值
- 动态关键字参数(Arbitrary Keyword Arguments) **kwargs
Python 3开始引入了“命名关键字参数”和“默认值的命名关键字参数”这两个概念。在这之前,所有的关键字参数都被视为可选的,没有默认值的关键字参数必须在调用时显式提供。
一个演示不同类型形参的函数(包括:位置参数、默认值位置参数、动态位置参数、关键字参数、默认值关键字参数、动态关键字参数)
def func(a, b, c=66, *args, d=10, e="default_d",  **kwargs):
    print("a:", a)
    print("b:", b)
    print("c:", c)
    print("d:", d)
    print("e:", e)
    print("args:", args)
    print("kwargs:", kwargs)
# 调用函数,演示各种参数传递方式
func(1, 2, 3, 4, 5, 6, 7, 8, d=30, e="test", x=77, y=88)
#运行结果
a: 1
b: 2
c: 3    #这里c的赋值是通过位置赋值给出的。
d: 30
e: test
args: (4, 5, 6, 7, 8)
kwargs: {'x': 77, 'y': 88}****如果调用代码中出现了c=???那么程序就会报错func(1, 2, 3, 4, 5, 6, 7, 8, c=33, d=30, e="test", x=77, y=88)
没有限制的接收任何参数
def func(*args, **kwargs):  # 没有限制的接收任何参数
    print(args, kwargs)
func()  # (), {}
func(1) #  (1, ), {}
func(1,2,3,4,4, a=2)  # (1,2,3,4,4), {"a":2}
func(1,2,3,4, c=4, a=2)# (1,2,3,4), {"c":4, "a":2}实参位置调用列表和字典
将列表中的所有元素,打散放入到函数中执行
stu_lst = ["流川枫", '樱木', "大老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王", "隔壁二老王"]
def func(*args):
    print(args)
func(*stu_lst)    # *在实参位置, 是把列表打散成位置参数进行传递
#执行结果
('流川枫', '樱木', '大老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王', '隔壁二老王')如果你有一个字典,想要将字典的键和值作为参数传递给函数,可以使用 ** 运算符来展开字典。
stu_dict = {"姓名": "流川枫", "班级": "一年级", "成绩": 90}
def func(**kwargs):
    print(kwargs)
func(**stu_dict)    # **在实参位置, 可以把字典打自动转化成关键字参数进行传递
#运行结果
{'姓名': '流川枫', '班级': '一年级', '成绩': 90}Python——第三章:函数的定义的更多相关文章
- 简学Python第三章__函数式编程、递归、内置函数
		#cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ... 
- Python第六章-函数01-函数的概念和使用
		函数 为了便于程序的维护和更好的实现模块化,好的程序都会分解为很多函数. 可以这么说,对于任何的编程语言,函数都是一个非常重要的概念. python 不仅简化了函数的定义过程,而且还大量借鉴了其他函数 ... 
- Python第六章-函数02-函数的作用域
		函数 三.作用域规则 有了函数之后,我们必须要面对一个作用域的问题. 比如:你现在访问一个变量,那么 python 解析器是怎么查找到这个变量,并读取到这个变量的值的呢? 依靠的就是作用域规则! 3. ... 
- python的三个函数(eval、exec、complie)和python版RMI
		一.python的三个函数: 1.eval函数: 之前已经讲过了这个函数,该函数也类似于php的eval,例如下边这个例子 eval("os.system('id')") 但是有个 ... 
- Python之旅.第三章.函数4.01/4.02
		一.三元表达式 #普通的判断大小函数def max2(x,y): if x > y: return x else: return yres=max2(10,11)print(res)x=12y= ... 
- Python之旅.第三章.函数3.28
		一.命名关键字参数: 什么是命名关键字参数?格式:在*后面参数都是命名关键字参数特点:1 必须被传值1 约束函数的调用者必须按照key=value的形式传值2 约束函数的调用者必须用我们指定的key名 ... 
- Python之旅.第三章.函数3.26
		一.函数: 1.为什么要有函数?什么是函数? 1.组织结构不清晰,可读性差 2.代码冗余 3.管理维护的难度极大,扩展性 具备某一个功能的工具就是程序的中函数 事先准备工具的过程---->函数的 ... 
- python第三章:函数
		在前面章节中,介绍了一些input(),print(),len()等内建函数,还有random,math等标准库相关函数,这些都是可以直接使用的,但是很多时候,我们也是可以编写自己的函数. 看个例子: ... 
- Python 基础三 文件 函数
		今天回顾一下之前学的文件操作相关知识点,对于文件的操作,主要有一下几部分构成: 一.文件的基础知识 1.文件操作的基本流程 文件操作其实可以分成三大部分: 1.打开文件,获取文件句柄并赋予一个变量 2 ... 
- 人生苦短我用Python 第三周 函数周
		函数的定义: 1,def 函数名(参数1,参数2......): "注释:函数的作用和参数,增加可读性", 2,函数体 3,返回值 最简单的函数: def func(): prin ... 
随机推荐
- 使用mtrace追踪JVM堆外内存泄露
			原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 简介 在上篇文章中,介绍了使用tcmalloc或jemalloc定位native内存泄露的方法,但使用这个方法相 ... 
- “&”控制命令的运行方式
			在Unix.Linux和类Unix系统中,& 符号有特定的意义,用于控制命令的运行方式.具体来说,& 在命令末尾使用时表示将该命令放入后台运行. 前台运行: 如果你在终端输入一个命令, ... 
- 再学Blazor——扩展方法
			上篇提到 Blazor 组件的高级写法,是采用扩展方法对 HTML 元素和组件进行扩展,以便于书写组件结构和代码阅读.本篇主要介绍扩展方法实现的思路. 什么是扩展方法 要扩展哪个类 扩展方法的实现 1 ... 
- 深入探讨I/O模型:Java中的阻塞和非阻塞和其他高级IO应用
			引言 I/O(Input/Output)模型是计算机科学中的一个关键概念,它涉及到如何进行输入和输出操作,而这在计算机应用中是不可或缺的一部分.在不同的应用场景下,选择正确的I/O模型是至关重要的,因 ... 
- 内存与CPU:计算机默契交互的关键解析
			内存 内存和CPU之间的交互是计算机体系结构中至关重要的一部分.它们之间的互动类似于一对不可分割的爱侣,彼此相互依赖且密不可分.没有内存,CPU无法执行程序指令,这样计算机就会变得毫无意义.同样地,如 ... 
- Android Kotlin 协程初探
			1 它是什么(协程 和 Kotlin协程) 1.1 协程是什么 维基百科:协程,英文Coroutine [kəru'tin] (可入厅),是计算机程序的一类组件,推广了协作式多任务的子程序,允许执行被 ... 
- golang在win10安装、环境配置 和  goland开发工具golang配置 及Terminal的git配置
			前言 本人在使用goland软件开发go时,对于goland软件配置网上资料少,为了方便自己遗忘.也为了希望和我一样的小白能够更好的使用,所以就写下这篇博客,废话不多说开搞. 一.查看自己电脑系统版本 ... 
- JUC并发编程学习笔记(十五)JMM
			JMM 请你谈谈对Volatile的理解 Volatile是java虚拟机提供的轻量级的同步机制 1.保证可见性 2.不保证原子性 3.禁止指令重排 什么是JMM JVM->java虚拟机 JM ... 
- 飞码LowCode前端技术系列:如何便捷快速验证实现投产及飞码探索
			本篇文章从数据中心,事件中心如何协议工作.不依赖环境对vue2.x.vue3.x都可以支持.投产页面问题定位三个方面进行分析. 一.数据中心,事件中心设计 飞码是数据驱动+事件驱动的产品,考虑到飞码运 ... 
- DFS深搜小谈
			前几天有人跟我说,啊,说dfs一搜搜着搜着就把自己搜蒙了,说一写dfs就要dfs(int a,int b,int c),括号里面放一堆东西.啊今天我要澄清一下,dfs其实没有你想的那么复杂. dfs这 ... 
