Python函数的基础学习

Python函数的基础学习

  • 一、函数分类
  • 二、函数基本形式
  • 三、形参与实参
    • 1、定义理解
    • 2、改变形对实参的影响
  • 四、参数类型
    • 1、位置参数
    • 2、默认值参数
      • 1、默认值参数位置问题
      • 2、理解默认值参数只在函数定义时被解释一次
    • 3、关键字参数
      • (1)普通关键字参数
      • (2)强制关键字参数
        • 普及参数及变量前加参数:
    • 4、可变长度参数

一、函数分类

(1)内置函数。Python语言内置了若干常用的函数,例如abs()、len()等等,在程序中可以直接使用。
(2)标准库函数。Python语言安装程序同时会安装若干标准库,例如math、random等等。通过import语句,可以导入标准库,然后使用其中定义的函数。
(3)第三方库函数。Python社区提供了许多其他高质量的库,如Python图像库等等。下载安装这些库后,通过import语句,可以导入库,然后使用其中定义的函数。
(4)用户自定义函数。本章将详细讨论函数的定义和调用方法。

二、函数基本形式

def 函数名([参数列表]):
‘’‘注释’’’
函数体
例如:

def main():print('hello')main()

注意事项

函数形参不需要声明类型,也不需要指定函数返回值类型

即使该函数不需要接收任何参数,也必须保留一对空的圆括号

括号后面的冒号必不可少

函数体相对于 def 关键字必须保持一定的空格缩进

Python允许嵌套定义函数

三、形参与实参

1、定义理解

形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。
实参出现在主调函数中,进入被调函数后,实参变量也不能使用。
1、形参只是在函数定义时使用;
2、实参是在函数调用时赋予的实际数值;

def ad(x,y):     #此时x,y是形参,ad是被调函数    c = x + y    return c    def main():    a=1          #此处a,b是实参    b=2          #此处a,b是实参    d = ad(a,b)  #此处a,b是实参,a.b在主调函数main中可以使用,但在被调函数ad中只能用x,y    print(d)main()

    函数定义时小括号内为形参,形参不需要声明类型,一个函数可以没有形参,但是小括号必须要有,表示该函数不接受参数。参数个数并没有限制,若有多个形参,需要使用逗号进行分割。
  函数调用时向其传递实参,将实参的值或引用传递给形参。

2、改变形对实参的影响

(1)对于绝大多数情况下,在函数内部直接修改形参的值不会影响实参。
样例:

def change(n):    n+=1    print('a通过函数change改变后的值:',n)       def main():    a=1    print('a的初始默认值:',a)    change(a)    print('验证a的实参值是否被函数中形参所影响:',a)main()

运行结果是:

a的初始默认值: 1a通过函数change改变后的值: 2验证a的实参值是否被函数中形参所影响: 1

可见函数内部直接修改形参的值不会影响实参
(2)如果传递给函数的是可变序列,并且在函数内部使用下标或可变序列自身的方法增加、删除元素或修改元素时,修改后的结果是可以反映到函数之外的,实参也得到相应的修改。

样例:

def change(n):    b=[4,5,6]    n.extend(b)    print('a通过函数change改变后的值:',n)   def main():    a=[1,2,3]    print('a的初始默认值:',a)    change(a)    print('验证a的实参值是否被函数中形参所影响:',a)main()

运行结果是:

a的初始默认值: [1, 2, 3]a通过函数change改变后的值: [1, 2, 3, 4, 5, 6]验证a的实参值是否被函数中形参所影响: [1, 2, 3, 4, 5, 6] #程序猿用事实说话,懂了吧!

四、参数类型

在 Python 中,函数参数有很多种:可以为普通参数、默认值参数、关键字参数、可变长度参数等等。

Python 在定义函数时不需要指定形参的类型,完全由调用者传递的实参类型以及 Python 解释器的理解和推断来决定,类似于重载和泛型。
Python 函数定义时也不需要指定函数返回值的类型,这将由函数中的 return 语句来决定,如果没有 return 语句或者 return 没有得到执行,则认为返回空值 None。

仅仅是不需要指定,并非完全不能指定,Python支持对函数参数和返回值类型的标注,但实际上并不起任何作用,只是看起来方便。
例如:

def change(n:str)->str:    #此处俩种指定“:str”和“->str”都是错误的,n应该是int型才对,但这不影响结果,不会出异常。    n+=1    print('a通过函数change改变后的值:',n)       def main():    a=1    print('a的初始默认值:',a)    change(a)    print('验证a的实参值是否被函数中形参所影响:',a)main()

运行结果:

a的初始默认值: 1a通过函数change改变后的值: 2验证a的实参值是否被函数中形参所影响: 1

1、位置参数

位置参数(positional arguments)是比较常用的形式,就是指调用函数时实参和形参的顺序必须严格一致,并且实参和形参的数量必须相同。

函数按位置传递参数

def change(a,b,c):   print(a,b,c)     def main():   a=1   b=2   c=3   change(a,c,b)   #形参按实参传入位置来顺序获取值main()

所以结果是:

1 3 2

实参与形参数量若不相同报异常

def change(a,b,c,d):    #多出一个d形参   print(a,b,c)     def main():   a=1   b=2   c=3   change(a,c,b)main()

因为形参多了一个而实参未能满足,所以结果是:

change(a,c,b)TypeError: change() missing 1 required positional >argument: 'd'

2、默认值参数

1、默认值参数位置问题

默认值参数必须出现在函数参数列表的最右端,且任何一个默认值参数右边不能有非默认值参数。

(1)错误样例就是最右端不是默认值参数:

def change(a,b=0,c,d):    #默认值参数b不在最右端    print(a,b,c,d)       def main():    a=1    b=2    c=3    d=4    change(a,b,c,d)main()结果是:def change(a,b=0,c,d):              ^SyntaxError: non-default argument follows default argument

其实我认为这里可能是因为涉及后面要讲的默认值参数可赋值可不赋值,到时不赋值默认值参数,默认值参数若不放在最后就会出现上面的位置参数问题,不好对应。
(2)正确样例1:(最右端是默认值参数)

def change(a,b,c,d=0):     #默认值参数d在最右端    print(a,b,c,d)       def main():    a=1    b=2    c=3    d=4    change(a,b,c,d)main()结果:1 2 3 4

正确样例2:(默认值参数右端都是默认值参数)

def change(a,b=3,c=2,d=0):      #默认值参数b的右端都是默认值参数    print(a,b,c,d)       def main():    a=1    b=2    c=3    d=4    change(a,b,c,d)main()结果:1 2 3 4

2、理解默认值参数只在函数定义时被解释一次

(1)首先理解默认值参数就是已经有默认值了,可以不传给它实参
例如:

def change(a,b=3):    b+=a    return b       def main():    print(change(1))    #这里只给a传了值,b有默认值    main()结果是:4

(2)python解释器对于默认值参数的赋值只会在函数定义时被解释一次。

也可以理解为默认值只存在存储区一次,谁先用了就归谁。

错误样例:

def change(a,b=[1,2,3]):    # b[2]的默认值为3    b[2]+=a    return b[2]             # 该函数功能就是求a+b[2]的和       def main():    print('第一次结果:',change(1,[1,2,2]))         #本意是求1+2    print('第二次结果:',change(3,[1,2,4]))         #本意是求3+4    print('第三次结果:',change(5))                 #本意是求5+3    print('第四次结果:',change(2))                 #本意是求2+3main()结果如下:第一次结果: 3第二次结果: 7第三次结果: 8第四次结果: 10

理解:

*第一次print中为b赋值了,没用b的默认值,在被调函数change中b直接使用被赋的值2,保留默认值3。即python解释器不需要对b的默认值进行解释。所以直接计算1+2,结果正确
*第二次print中也为b赋值了,仍没用b的默认值,在被调函数change中b使用被赋的值4,保留默认值3。即python解释器不需要对b的默认值进行解释。所以直接计算3+4,结果正确
*第三次print中没对b赋值,b需要使用自身默认值,在这里默认值被用掉,即python解释器对b的默认值进行了唯一的一次解释,之后不在解释,也就是b没有了默认值,或者说是b之后的默认值就是b的值,会随函数的改动而改动,毕竟之后还是可以对b不传值的,b也还是默认值参数。这里计算的就是5+3的值,结果正确
*第四次print中没对b赋值,也就如上面所说b没有了默认值,或者说是b之后的默认值就是b的值,会随函数的改动而改动。因此此处b的默认值就是上次函数调用结束时b的值,上次b+=a后b是8,所以这里计算的是8+2,与我们预期的算3+2不符,结果错误。

若想达到预期,需将代码改为:

def change(a,b=None):       #这里只能是None,不能写b=[ ]    if b is None:           #这里也一样,不能是[ ]        b=[1,2,3]    b[2]+=a    return b[2]       def main():    print('第一次结果:',change(1,[1,2,2]))    print('第二次结果:',change(3,[1,2,4]))    print('第三次结果:',change(5))    print('第四次结果:',change(2))main()结果如下:第一次结果: 3第二次结果: 7第三次结果: 8第四次结果: 5

需要注意这种错误仅对应于可变序列,对于不可变或实数不成立
举例实数:

def change(a,b=3):    # b的默认值为3    b+=a    return b          # 该函数功能就是求a+b[2]的和       def main():    print('第一次结果:',change(1,2))    #本意是求1+2    print('第二次结果:',change(3,4))    #本意是求3+4    print('第三次结果:',change(5))      #本意是求5+3    print('第四次结果:',change(2))      #本意是求2+3main()结果如下:第一次结果: 3第二次结果: 7第三次结果: 8第四次结果: 5

可见对于不可变序列默认值始终不变,这就像是形参与实参中的可变序列的形参改变会影响到实参一样,在这里可变序列的改变会影响到它的默认值。
类似可变默认值,实则不是的例子:

def main():    x=2    def change(a,b=x):   #在这里b就已经将默认值设为2,                         #看起来像是b的默认值随x变化而变化,                         #其实这里类似与(a,b=2),是不可变的。        b+=a        return b    x=4    print('第一次结果:',change(2,x))    print('第二次结果:',change(2))    print('第三次结果:',change(2))main()运送结果:第一次结果: 6第二次结果: 4第三次结果: 4

第一次赋值了,而且x的值改为了4,第一次结果与预期一致。
第二次使用了默认值,由结果可知在函数定义时b的默认值已确定,在x改变后b的默认值未变。
有第三次结果可知b的默认值没有在第二次运算中改变,就是相当于不可变默认值。

3、关键字参数

(1)普通关键字参数

关键字参数主要指实参,即调用函数时的参数传递方式。
通过关键字参数,参数按名称传递意义明确;传递参数时与形参顺序无关;如果有多个可选参数,则可以选择指定某个参数值。
对比以下俩代码:

样例1def change(a,b,c):    print(a,b,c)       def main():    x,y,z=1,2,3    change(a=x,b=y,c=z)    #按序输入main()结果是:1 2 3
样例2def change(a,b,c):    print(a,b,c)       def main():    x,y,z=1,2,3    change(a=x,c=z,b=y)    #对形参b,c的输入顺序改变main()结果是:1 2 3

由此可见有关键字以后,可以直接对形参指定赋值,不必再依照位置参数。

(2)强制关键字参数

普及参数及变量前加参数:

1、函数声明的参数列表中加单星号,即f(*x)则表示x为元组,所有对x的操作都应将x视为元组类型进行。所有传入f(*x)的变量都将作为元组x的元素之一。

2、双星号同上,区别是x视为字典。

3、在变量前加单星号表示将元组(列表、集合)拆分为单个元素。

4、双星号同上,区别是目标为字典,字典前加单星号的话可以得到“键”。

在带星号的参数后面声明的参数强制为关键字参数,如果这些参数没有默认值,则调用时必须使用关键字参数赋值,否则会引发错误。
如果不需要带星号的参数,只需要强制关键字参数,则可以简单地使用一个星号,如 def total(initial=5, *, vegetables)

来用几个样例说明这段话:

样例1(星号后使用关键字参数赋值):def change(a,*b,c,d,e):  #*b既将被视为元组,也将c,d,e强制为关键字参数    print(a,b,c,d,e)     #b直接输出是元组形式       def main():    x,y,z,s,t=1,2,3,4,5    change(x,y,c=z,d=s,e=t)    #c,d,e使用关键字参数赋值main()运行结果:1 (2,) 3 4 5
样例2(星号后未用关键字参数赋值):def change(a,*b,c,d,e):  #*b既将被视为元组,也将c,d,e强制为关键字参数    print(a,b,c,d,e)     #b直接输出是元组形式       def main():    x,y,z,s,t=1,2,3,4,5    change(x,y,z,d=s,e=t)     #c未使用关键字参数赋值,是按照位置参数赋值的main()结果异常: change(x,y,z,d=s,e=t)TypeError: change() missing 1 required keyword-only argument: 'c'

通过样例1,2可知星号后被强制关键字的参数必须用关键字参数赋值

样例3(星号后有默认值参数,用关键字参数赋值,对默认值参数不赋值):def change(a,*b,c,d=999,e):  #*b既将被视为元组,也将c,d,e强制为关键字参数,d是默认值参数    print(a,b,c,d,e)         #b直接输出是元组形式       def main():    x,y,z,s,t=1,2,3,4,5    change(x,y,c=z,e=t)      #c,e使用关键字赋值,默认值参数d未赋值main()运行结果:1 (2,) 3 999 5

样例3中可知虽然被强制为关键字参数但默认值参数还是可以不赋值。
但还有一个发现,那就是被强制关键字参数后,默认值参数不必再位于最右端。

样例4(星号后有默认值参数,用关键字参数赋值,对默认值参数用位置参数赋值):def change(a,*b,c,d=999,e):  #*b既将被视为元组,也将c,d,e强制为关键字参数,d是默认值参数    print(a,b,c,d,e)         #b直接输出是元组形式       def main():    x,y,z,s,t=1,2,3,4,5    change(x,y,c=z,s,e=t)    #c,e使用关键字赋值,默认值参数d用位置参数赋值main()运行结果:    change(x,y,c=z,s,e=t)                  ^SyntaxError: positional argument follows keyword argument
样例5(星号后有默认值参数,用关键字参数赋值,对默认值参数用关键字参数赋值):def change(a,*b,c,d=999,e):  #*b既将被视为元组,也将c,d,e强制为关键字参数,d是默认值参数    print(a,b,c,d,e)         #b直接输出是元组形式       def main():    x,y,z,s,t=1,2,3,4,5    change(x,y,c=z,d=s,e=t)  #c,e使用关键字赋值,默认值参数d用关键字参数赋值main()运行结果:1 (2,) 3 4 5

由样例3、4、5可知,对于被强制为关键字参数的默认值参数可以不传值,但如果要赋值也只能用关键字参数赋值。

样例6(理解不需要带星号的参数,只需要强制关键字参数,则可以简单地使用一个星号):def change(a,*,c,d=999,e):  # *之后的c,d,e都被强制为关键字参数,没有了*b,也就是不需要元组,只需牵制关键字参数    print(a,c,d,e)          #直接输出的结果中将不再有元组形式       def main():    x,y,z,s,t=1,2,3,4,5    change(x,c=z,d=s,e=t)   # *之后的都采用了关键字赋值main()运行结果:1 3 4 5

4、可变长度参数

可变长度参数主要有两种形式:
*参数用来接受多个实参并将其放在一个元组中
**参数用来接受关键字参数并存放到字典中
这个在上面强制关键字参数中有提及,*不光会将之后的参数强制为关键字参数,也会将它贴着的参数视为元组,上面样例中有。
下面讲讲如何将多个实参传入这种元组或字典中,
这里要注意,由于强制关键字参数的缘故,可变长度参数要放在最右端。

def change(a,b,*c):  #*c既将被视为元组,即可变长度参数    print(a,b,c)     #c直接输出是元组形式       def main():    x,y=1,2    change(x,y,1,2,3,4,5)  #前面x、y以位置参数的方式对a、b赋值,后面的多个实参都将作为元组c的元素main()运行结果:1 2 (1, 2, 3, 4, 5)
def change(a,b,*c,**d):  #*c既将被视为元组,d被视为字典,即可变长度参数    print(a,b,c,d)       #c直接输出是元组形式,d以字典形式输出       def main():    x,y=1,2    change(x,y,1,2,3,4,5,r=11,s=22,t=33)   # =形式的参数被识别为字典元素main()运行结果:1 2 (1, 2, 3, 4, 5) {'r': 11, 's': 22, 't': 33}

补充一下:虽然字典元组可以混用,但不鼓励用,还有就是若没给例如=形式的参数,输出的字典将显示空{},不会错。

(0)

相关推荐

  • python再谈函数

    python再谈函数

  • 第13天:Python 函数的参数

    定义一个函数非常简单,但是怎么定义一个函数,需要什么参数,怎么去调用却是我们需要去思考的问题. 如同大多数语言一样(如 Java),Python 也提供了多种参数的设定(如:默认值参数.关键字参数.形 ...

  • python函数传入数量可变参数

    def func(x,y,**kwargs): print(x,y,kwargs) func(x=2,y=1,3,4)#这样传入参数为错误,**需要赋值给一个变量名,然后传入为字典性形式func(x= ...

  • 【python学习笔记】函数参数传递方法

    【python学习笔记】函数参数传递方法

  • 函数与Lambda表达式

    函数参数定义 # 学习人员:贾其豪# 开发时间:2021/1/31 14:05#函数定义默认值参数#函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参def fun(a,b=10): ...

  • 教你一招 | Python: 函数参数魔法

    函数参数 在 Python 中,定义函数和调用函数都很简单,但如何定义函数参数和传递函数参数,则涉及到一些套路了.总的来说,Python 的函数参数主要分为以下几种: 必选参数 默认参数 可变参数 关 ...

  • python到底还有哪些函数我们还没见过?原来有这么多实用的函数

    本文将将主要介绍如下内容 函数介绍 1.1 函数的定义 所谓的函数,其实就是具有特定功能的一段代码块,都可以独立的运行 . 函数有5部分组成,分别是定义函数的关键字,函数的名字,圆括号(存放函数的参数 ...

  • Python中tuple和list的区别?基础学习!

    想必大家都知道,Python数据类型有很多种,其中有两个对象的写法非常相似,它就是tuple元组和list列表,让人傻傻分不清楚.那么你知道Python中tuple和list有什么区别吗?我们来看看具 ...

  • Excel中Search函数的基础认识与进阶学习!

    Excel情报局 Excel职场联盟 生产挖掘分享Excel基础技能 Excel爱好者大本营 用1%的Excel基础搞定99%的职场问题 做一个超级实用的Excel公众号 Excel是门手艺玩转需要勇 ...

  • Python基础学习笔记(十三)图形化界面Tkinter

    本节知识大纲: 本节知识框架 Python里的图形化界面(GUI)模块主要有Tkinter(python自带).PyQt.wxPython,我们这节主要讲解Tkinter组件: 一.Tkinter介绍 ...

  • 学习计划|一个月学会Python,零基础入门数据分析

    在数据分析领域,python是一个绕不开的知识和工具,如果不会用python就很难说自己会数据分析,但是最近很多想要入门数据分析的小白经常问我,Python怎么入门?Python虽然被称作是" ...

  • Python基础学习笔记(八)异常处理

    本节知识大纲: 本节知识大纲 一.概念 什么是异常? 在程序运行过程中发生错误和意外,这些错误和意外往往不是语法错误. 定义:语法错误不属于异常,因为语法错误没办法让软件正常运行:正确情况下的异常指的 ...

  • Python基础学习笔记(一)变量与数据类型

    https://m.toutiao.com/is/J3fN6eK/ Python是一门易学的面向对象的程序设计语言,可以轻易地完成界面.文件.封装等高阶需求,可移植性好,有非常多功能强大的库与包,如N ...

  • Python基础学习3——编程语言基本概念

    编程语言的分类(概念) https://m.toutiao.com/is/J7gQwRK/ 编译型语言: 产生一个额外的文件,电脑能够识别的内容.运行是直接运行编译后的额外的文件. 解释型语言: 不会 ...

  • Python基础学习笔记(五)集合与字典

    本节知识大纲: 集合 字典 一.Set 集合的概念 1. set 集合的性质 set 集合是一组无序的且不能重复的集合,打印 set 集合时会自动消除重复的元素项: set 集合用大括号表示: set ...

  • 新手上路必学的Python函数基础知识,全在这里了(多段代码举例)

    简说Python 164篇原创内容 公众号 大家好,我是老表,这篇文章比较长(近万字),干货很多,值得收藏:文末还有赠书活动(送五本<利用Python进行数据分析>(原书第2版)),祝大家 ...