美文网首页
【python】函数的位置参数/默认参数/可变参数/关键字参数/

【python】函数的位置参数/默认参数/可变参数/关键字参数/

作者: SimonJoe246 | 来源:发表于2018-01-30 18:20 被阅读0次

    位置参数

    我们在利用函数计算一个数的平方时,必须要给这个函数传入一个参数——即我们要计算平方的数。

    def pow(x):
        return x * x
    

    对于函数pow来说,x就是一个位置参数,当调用这个函数时,x是必须传入有且唯一的一个参数。

    当我们想计算 x3,可以定义另一个函数,那求x4呢,还要再定义吗,其实我们只需对pow函数稍加改动即可

    def pow(x, n):
        prod = 1
        while n > 0:
            prod = prod * x
            n = n-1
        return prod
    

    这时,x 和 n 就都是位置参数,在调用时必须同时传入,按照顺序依次赋值给x 和 n。

    默认参数

    在实际应用中我们必须考虑这种情况:一般求幂都是求平方,每次使用pow函数都要输入两个参数未免太麻烦了些,所以有了默认参数,即这个参数有个缺省值,在不输入是默认为缺省值。

    【例1】:

    def pow(x, n = 2):
        prod = 1
        while n > 0:
            prod = prod * x
            n = n-1
        return prod
    

    当把n由变成n=2时,位置参数就变成了默认参数,当我们只传入一个参数时,n默认为2。即pow(3)计算的是32

    对于其他n>2的情况,就必须要传入两个参数了。

    使用默认参数有以下情况需要注意:

    • 函数的参数可以全由默认参数组成

    • 但当位置参数和默认参数同时存在时,默认参数必须定义在位置参数的后面,否则会报错

    • 如何设置默认参数:
      一般把变化大的设为位置参数,变化小的(默认值使用次数占多)设为默认参数,如【例1】 的pow函数

    当有多个默认参数时,可以不按照默认参数的定义顺序给出,但必须同时给出参数名称,如【例2】:

    【例2】:

    def enroll(name, gender, age = 6, city = 'Beijing', district = 'Chaoyang'):
        print('name:', name)
        print('gender:', gender)
        print('age:', age)
        print('city:', city)
        print('district:', district)
    

    我们可以这样调用:enroll('xiaoming', 'M', district = 'Jizhou', city = 'Tianjin')

    运行结果:

    name: xiaoming
    gender: M
    age: 6
    city: Tianjin
    district: Jizhou
    

    重点:默认参数必须指向不变对象

    【例3】:

    def add_end(L = []):
        L.append('end')
        return L
    

    当我们第一次运行该函数时,结果正常:

    >>> add_end()
    ['end']
    

    但当我们再运行时,会发现:

    >>> add_end()
    ['end', 'end']
    >>> add_end()
    ['end', 'end', 'end']
    

    每次运行都会记录这个添加的end结尾,但这并非我们的本意,究竟为何如此呢?

    我们定义的默认参数L是个变量,其指向为 [] 这个list,但运行一次之后,其指向的list内容发生了改变,已经变成['end'],默认参数的内容就变了,不再是函数定义时的 [] 了。

    所以:

    定义默认参数要牢记一点:默认参数必须指向不变对象!

    有哪些数据类型是不变对象呢,比如:str,None,不变对象一旦创建,其内部数据便不可更改,减少了由于修改数据导致的错误。

    可变参数

    可变参数,顾名思义,就是传入参数的数量可以变化,可以是1个,2个,3个……

    【例4】:

    def cal(numbers):
        sum = 0
        for x in numbers:
            sum = sum + x
        return sum
    

    由此我们可以计算1+2+4+5+8+...的值了,但每次调用我们传入的numbers参数必须是一个 list 或 tuple,较麻烦。此时的numbers是一个位置参数,不是可变参数。

    稍加改动,即可将 numbers 定义为一个可变参数

    【例4.1】

    def cal(*numbers):
        sum = 0
        for x in numbers:
            sum = sum + x
        return sum
    

    只是在numbers前加了个*,numbers就成为了可变参数,我们在调用此函数时可以这样调用:

    cal(1,2,3,6,7,8),此时numbers接收到的是一个tuple,函数代码不变,函数即可传入任意个参数,包括0个参数。

    >>> cal(3,56,7,8)
    74
    >>> cal()
    0
    

    如果numbers是位置参数时则0个参数会报错,因为位置参数是必须传入的。

    当我已经有一个 list 或 tuple 了怎么把它传入函数中,可以这样做:

    >>> num = [1,3,5,6,7,8]
    >>> cal(*num)
    30
    

    在 list 或 tuple 前加一个*就能将其传入函数中了。

    关键字参数

    可变参数是可以传入任意个(包括0个)参数,这些可变参数在传入时会自动组装成一个tuple。关键字参数是允许你传入任意个(包括0个)含参数名的参数,这些关键字参数会自动组装成为一个dict

    【例5】:

    def person(name, age, **kw):
        print('name:', name, 'age:', age, kw)
    

    函数person在调用时除了接受必选参数nameage,还接受关键字参数kw。调用时可以只传入位置参数

    >>> person('xiaoming','6')
    name: xiaoming age: 6 {}
    

    也可以传入任意个数的关键字参数:

    >>> person('xiaoming','6',city = 'Beijing', job = 'Engineer')
    name: xiaoming age: 6 {'city': 'Beijing', 'job': 'Engineer'}
    

    可以看到,两个关键字参数已经自动组成为dict了。

    应用场景:

    在用户注册时,用户可以只填入姓名,年龄两个参数,但提供城市,职业等参数选填。

    与可变参数相同,我们也可以提前组装好一个dict,之后利用**dict名将其传入函数:

    >>> d = { 'city' : 'Beijing', 'job' : 'Engineer'}
    >>> person('xiaoming', 6, **d)
    name: xiaoming age: 6 {'city': 'Beijing', 'job': 'Engineer'}
    

    **d会将此dict的所有key-value用关键字参数传入到函数的**kw参数中,kw将获得一个dict,其获得的是d的一份拷贝,对**kw做任何改动不会影响d

    命名关键字参数

    关键字参数允许我们传入任意个含参数名的关键字参数,但是考虑到限制用户输入的随意性,如何让用户只传入规定的关键字参数呢。比如,只接受cityjob作为关键字参数,可以这样定义:

    def person(name, age, *, city, job):
        print(name, age, city, job)
    

    和关键字参数**kw不同,命名关键字参数只需要一个特殊分隔符**后面的参数都会被视为命名关键字参数。

    调用方式如下:

    >>> person('xiaoming',6,city = 'Beijing', job = 'Engineer')
    xiaoming 6 Beijing Engineer
    

    命名关键字参数调用时必须写参数名,不写的话函数会默认将其视为位置参数,将会报错。

    如果命名关键字参数前面有可变参数,则省略*作为分隔符,可变参数后的参数自动视为命名关键字参数,不必担心混淆,命名关键字参数传入时必须包含参数名。

    def person(name, age, *args , city, job):
        print(name, age,args, city, job)
    
    >>> person('xiaoming',6, 'This is a smart boy', 'allergic to egg', city = 'Beijing', job = 'Engineer')
    xiaoming 6 ('This is a smart boy', 'allergic to egg') Beijing Engineer
    

    命名关键字参数也可以有缺省值,从而简化调用:

    def person(name, age, *args , city = ‘Beijing, job):
        print(name, age,args, city, job)
    
    >>> person('xiaoming',6, 'This is a smart boy', 'allergic to egg', job = 'Engineer')
    xiaoming 6 ('This is a smart boy', 'allergic to egg') Beijing Engineer
    

    注意:

    使用命名关键字参数时,如果前面没有可变参数,必须加特殊分隔符*。如果不加,python将无法识别位置参数和命名关键字参数。

    参数组合

    这五种参数可以组合使用,但参数定义的顺序必须是:

    位置参数-->默认参数-->可变参数-->命名关键字参数-->关键字参数

    注意命名关键字参数和关键字参数的顺序。

    比如定义一个函数,包含若干上述参数:

    def f1(a, b, c=0, *args, **kw):
        print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
    def f2(a, b, c=0, *, d, **kw):
        print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
    

    可以看出,

    f1包含位置参数,默认参数,可变参数,关键字参数。

    f2包含位置参数,默认参数,命名关键字参数,关键字参数。

    其中可变参数在传入时自动组成一个tuple,关键字参数传入时自动组成一个dict。

    函数调用时,python解释器会自动按参数位置和参数名把对应的参数传进去。

    f1可以只传入位置参数,f2必须传入的有位置参数,命名关键字参数。

    >>> f1(1,2)
    a = 1 b = 2 c = 0 args = () kw = {}
    >>> f1(1,2,4)
    a = 1 b = 2 c = 4 args = () kw = {}
    >>> f1(1,2,c=4)
    a = 1 b = 2 c = 4 args = () kw = {}
    >>> f1(1,2,4,'ab',2)
    a = 1 b = 2 c = 4 args = ('ab', 2) kw = {}
    >>> f1(1,2,4,'ab',2,city = 'Beijing')
    a = 1 b = 2 c = 4 args = ('ab', 2) kw = {'city': 'Beijing'}
    >>> f2(1,2,4,d = 6)
    a = 1 b = 2 c = 4 d = 6 kw = {}
    >>> f2(1,2,4,d = 6,city = 'Beijing')
    a = 1 b = 2 c = 4 d = 6 kw = {'city': 'Beijing'}
    >>> f2(1, 2, d=99, ext=None)
    a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
    

    最神奇的是,通过一个tuple和dict,你也可以调用上述函数:

    >>> args = (1,2,3,4)
    >>> kw = {'d':99,'x':'#'}
    >>> f1(*args,**kw)
    a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
    >>> args = (1, 2, 3)
    >>> kw = {'d':456,'city':'Beijing'}
    >>> f2(*args,**kw)
    a = 1 b = 2 c = 3 d = 456 kw = {'city': 'Beijing'}
    

    无论函数是如何定义的,都可以通过类似func(*args,**kw)的方式调用它。

    最后:

    不要同时使用太多的组合,会使函数接口的可理解性很差

    相关文章

      网友评论

          本文标题:【python】函数的位置参数/默认参数/可变参数/关键字参数/

          本文链接:https://www.haomeiwen.com/subject/msoqzxtx.html