zoukankan      html  css  js  c++  java
  • 函数参数详解

     # 函数参数详解
    # 一.位置参数
    # 二.关键字参数
    # 三.默认形参
    # 四.可变长参数

    参数根据定义阶段和调用阶段分为形参和实参

    形参:在定义阶段时括号内的指定的参数就称之为形式参数,本质就是一个名字
    实参:在函数调用阶段时括号内传入的参数,是一个实际的值
    另外,在调用函数的时候就会自动把形参(变量名)和实参(值)进行绑定
    当函数调用结束后,就自动解除绑定了
    def func(a,b): # a和b就是形参,a和b实际上就是变量名
    print(a)
    print(b)
    func(1,2) # 1和2就是实参,是被传入的值

    因为参数根据定义和调用分为形参和实参,所以无论是位置参数还是关键字参数也都做了详细的划分
    例如:位置参数又分为位置形参和位置实参
    一.位置参数
    位置,值的就是顺序,从左往右来定义的参数就是位置(顺序)参数
    需要注意的是,
    1.形参必须被传值
    2.位置形参和位置实参的数量必须保持一致,不能多传,也不能少传,否则就会报错
    3.实参会依照顺序依次赋值给形参
    例一
    def func(a,b,c) # a,b,c 都是位置形参
    print(a,b,c)
    func(1,2,3) # 1,2,3 都是位置实参
    func(1,2,3,4,5) # 语法错误: 实参与被传值的形参数量不一致

    例二
    def func(name,age,gender):
    print('my name is %s my age is %s my gender is %s' % (name,age,gender))
    func('egon',19,'male')


    二.关键字参数:在调用阶段指名道姓的为形参赋值,就称之为关键字实参
    优点:可以打破传入参数的顺序,关键字实参与形参的位置可以不一致
    注意:
    1.无论以哪种方式传值,形参都必须被传值
    2.关键字实参必须位于位置实参后面
    3.不能为同一形参传多次值
    4.使用关键字来传参是实参的名字必须与形参的名字一致

    (****) 到底是位置参数,还是关键字参数,都是由实参决定的

    案例一:
    def func(a,b,c):
    print(a,b,c)
    func(c=10,11,2) # 语法错误: positional argument follows keyword argument(关键字实参出现在了位置实参后面)
    func(1,2,a=10) #语法错误: a被传值两次,而c却没有被传值
    func(c=10,a=-20,b=5) #正确传参,可以打破顺序限制
    func(c=10,a=19,f=20) # 形参与实参的名字不一致所以也会报错

    案例二
    def register(name,pwd):
    print('name is',name)
    print('pwd is',pwd)
    register(pwd=123123,name='deng') # 可以不用完全按照顺序来传值
    register('egon',pwd=123123) # 可以用位置实参和关键字实参混合使用,但前提是关键字实参在位置实参前面

    三.默认形参:在定义函数是就已经为形参指定了一个值,那这个形参就是默认形参
    例如:def func(name,age,sex='male') # sex 就是默认形参
    特点:1.在调用函数的时候不用为默认传参传值,使用参数是就是默认值
    2.当然默认形参也可以被传值,这样内部使用的时候就是你传入的值

    使用场景:
    当一个函数中经常出现重复的值时,就可以将该形参定义为默认形参
    好处是可以简化很多重复操作

    需要注意:
    1.默认形参必须要放在非默认形参后面
    2.默认形参在定义阶段就已经固定了
    3.不应该将默认形参的默认值定义为可变类型
    会导致 每次函数调用都共用同一个默认参数,我们应该将函数设计为独立的功能 每次调用互不干扰
    因此,默认形参只能是 str int float tuple

    案例一:
    def register(name,age,sex='woman'): # 此时要被传值的参数大多是女性,所以可以把性别默认定义为woman
    print(name,age,sex)
    register('kong',22)
    register('luo',25)
    register('liu',26)
    register('cui',34,sex='man') #但是当有个别案例时,可以自定义传值

    案列二:
    def reg1(name,sex,hobby,li=[]): # 因为爱好有很多种类,因人而异,所以不应该设置为默认值
    li.append(hobby)
    print(name,sex)
    print(li)
    reg1('egon','man','music') # 此时不传值似乎也没有问题,请看下一步操作
    reg1('alex','sleep','play') # 只为alex的爱好传了play,可是执行结果却是['music', 'play'] ,
    # 因此,把默认参数定义为可变类型,会导致所有的调用者所共享,
    正确示范,不应该定义默认形参,
    def reg1(name,sex,hobby):
    print(name,sex)
    print(hobby)
    reg1("bgon","man",["music","play"])

    四.可变长参数: 是指可以传任意数量的实参
    传入实参是为了给形参使用,那就意味着,让形参具备接受任意数量的实参的能力
    也就是* 和 **

    1.*的使用:
    1) 带*的形参: 如案例一
    带*的形参可以接受任意数量的实参,那么就收到的实参会被打包成元组类型 如案例一
    带*的形参的名字可以随意,但是建议用args,是arguments的缩写
    带*的形参不能接收关键字实参
    (2) 带*的实参 案例二
    在实参前面带*,会自动将*后面的值打散,如案例二,将[9,'yx',10]列表中的每个元素打散,然后按照位置赋值给形参

    2.可变长形参和位置形参混合使用 案例三
    (1) 当可变长形参出现在位置形参前面,那么后面的位置形参必须使用关键字实参来传值
    (2) 当可变长形参出现在位置形参后面,会先按照顺序先给前面的位置形参赋值,最后剩余的就会赋值给可变长args
    3.**的使用: 案例四
    (1) 形参中带** ,会把关键字实参打包成字典传入
    注: **只能接受多出来的关键字实参,**不能接收位置实参
    (2) 实参中带**,会把**后的字典(也必须是字典类型)打散,成关键字实参(**{"a":1} 打散为 a = 1)




    案例一
    def func(*args):
    print(args)
    func(1)
    func(1,2,3,4,5)
    func(a=1) # 带*的形参不能接收关键字实参
    func(a=1,b=2)
    func(a=1,b=2,c=3


    案例二
    def func(a,b,c,d,e):
    print(a,b,c,d,e)
    func(1,2,*[9,'yx',10]) # 相当于func(1,2,,9,yx,10)
    func(1,2,[3,4,5,6,7]) # 当列表中的元素被打散,
    iterable 可迭代的 只要是可以被for循环使用的都是可迭代 字符串 列表 元组 字典 集合

    案例三
    def func(*args,a,b):
    print(a,b,args)
    func(1,2,3,4) # 可变长形参出现在位置形参前面,导致1,2,3,41全部传给了args,而a,b没有被赋值,所以会有语法错误
    func(1,2,3,4,b=10,a=20) # 当可变长参数出现在位置形参前面时,正确传参形式

    def func(a,b,*args):
    print(a,b,args)
    func(1,2,3,4,5,6,7) # 可变长形参(*args)出现在位置形参后面,先按顺序赋值给位置形参,剩余的全部赋值给*args,打包成元组

    案例四
    def func(**b):
    print(b)
    func(x=1,y=2,z='egon') # 将传入的关键字实参打包成字典 {'x': 1, 'y': 2, 'z': 'egon'}
    func(1,2,3,4) # 带**的形参不能接受位置实参,只接受关键字实参

    # def func(a,b,c,**e):
    # print(a,b,c,e) # 先为前面的形参赋值,后续的多余的关键字参数赋值给**
    # func(1,c=2,b='egon',rong=438,egon='cool') # 1 egon 2 {'rong': 438, 'egon': 'cool'}

  • 相关阅读:
    JavaScript中的闭包
    SQL 备忘
    SqlServer 2005 升级至SP2过程中出现"身份验证"无法通过的问题
    unable to start debugging on the web server iis does not list an application that matches the launched url
    Freebsd 编译内核
    Freebsd 6.2中关于无线网络的设定
    【Oracle】ORA01219
    【Linux】Windows到Linux的文件复制
    【Web】jar命令行生成jar包
    【Linux】CIFS挂载Windows共享
  • 原文地址:https://www.cnblogs.com/dengyanchuan/p/10282301.html
Copyright © 2011-2022 走看看