路漫漫其修远兮
吾将上下而求索

python学习:函数,默认参数,可变参数,关键字参数

函数说明
函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回
def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

如果你已经把my_abs()的函数定义保存为abstest.py文件了,那么,可以在该文件的当前目录下启动Python解释器,用
from abstest import my_abs来导入my_abs()函数,注意abstest是文件名(不含.py扩展名)

如果想定义一个什么事也不做的空函数,可以用pass语句:缺少了pass,代码运行就会有语法错误。
def nop():
    pass

    
函数返回多个函数值,其实返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接
收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便
import math

def move (x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

x,y = move (100, 100, 60, math.pi/6)
z = move (100, 100, 60, math.pi/6)

print (x, y)
print (z)

151.96152422706632 70.0
(151.96152422706632, 70.0)


当定义函数的默认参数时:默认参数可以简化函数的调用。设置默认参数时,有几点要注意:
一是必选参数在前,默认参数在后,否则Python的解释器会报错 (如果函数定义输入有两个值,为了安全可靠,可以指定
参数及对应值:enroll('Adam', 'M', city='Tianjin')
有多个默认参数时,调用的时候,既可以按顺序提供默认参数,比如调用enroll('Bob', 'M', 7),意思是,除了name,gender这
两个参数外,最后1个参数应用在参数age上,city参数由于没有提供,仍然使用默认值
可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。比如调用enroll(name='Adam'),意思
是,name参数用传进去的值,其他默认参数继续使用默认值。

定义默认参数要牢记一点:默认参数必须指向不变对象!不然会出问题
def add_end(L=None):    #def add_end(L=[]):  有问题,这个变量会一直存在,每次调用初始值不同
    if L is None:
        L = []
    L.append('END')
    return L
    

在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的
我们可以把a,b,c……参数作为一个list或tuple传进函数
def calc (numbers):
    sum = 0
    for n in numbers:
        sum = sum + n
    return sum

a = calc ([1,2,3,4,5])  #这里其实list是一个变量,传入函数
print (a)


我们把函数的参数改为可变参数
def calc (*numbers):
    sum = 0
    for n in numbers:   #这里接收的numbers其实是一个tuple
        sum = sum + n
    return sum

a = calc (1,2,3,4,5)
print (a)

当num为一个list,Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去
num = [1,2,3,4,5]
b = calc (*num)
print (b)


可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个
含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调
用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,
利用关键字参数来定义这个函数就能满足注册的需求。
def person(name, age, **kw):
    print ('name:', name, 'age: ', age, 'other: ', kw)

person('andy', 30, city = 'beijing', color = 'a')

结果:name: andy age:  30 other:  {'city': 'beijing', 'color': 'a'}
=========================================
def person(name, age, **kw):
    print ('name:', name, 'age: ', age, 'other: ', kw)

extra = {'city':'beijing','color':'yellow'}
person('andy', 30, **extra)

注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra

如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。就是说限制key的名字只能是city和job这两个
这种方式定义的函数如下:
def person(name, age, *, city, job):
    print(name, age, city, job)
    
person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。

*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3));
关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})。
使用*args和**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*,否则定义的将是位置参数。

在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。
但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
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)
>>> 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': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}


递归函数
def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)
    
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120

未经允许不得转载:江哥架构师笔记 » python学习:函数,默认参数,可变参数,关键字参数

分享到:更多 ()

评论 抢沙发

评论前必须登录!