函数参数这块在前面的博客中没有展开,现在专门整理出来:

1、参数的数量:

1)没有参数:就是定义函数和调用函数的括号中都不写内容。

2)有一个参数:可以是任何数据类型。

3)有多个参数:例如位置参数。

2、位置参数:

概念:按照从左到右的顺序依次定义的参数,就称之为位置参数。

位置形参:在定义函数阶段,按照从左到右的顺序直接定义的“变量名”。必须被传值、多一个不行、少一个也不行。

位置实参:在函数调用阶段,按照从左到右的顺序依次传入的值。

例1:

def my_sum(a, b):    # 位置形参
    res = a + b
    return res


ret = my_sum(1, 2)   # 位置实参
print(ret)

3、关键字参数:

关键字实参:在函数调用阶段, 按照key=value的形式传入的值。就是指名道姓地给某个形参传值,可以完全不参照顺序。

例2:

def my_sum(a, b):
    res = a + b
    print('a: ', a)
    print('b: ', b)
    return res


ret = my_sum(b=1, a=2)

print(ret)

4、默认参数(默认形参): 在定义函数阶段,就已经被赋值的形参,称之为默认参数。在定义阶段,就被赋值,意味着在调用阶段就不用再为其赋值,也就是可以不传。

注意:所有位置参数必须出现在默认参数前,包括函数定义和调用。

例3:

def my_sum(a, b=7):    # b是默认参数,有默认值7
    res = a + b
    print('a: ', a)
    print('b: ', b)
    return res


ret = my_sum(1)        # 调用时,就不用再为b赋值了

print(ret)

5、位置形参和默认参数(默认形参)可以混合使用:

1、规则:位置形参必须位于默认形参的左边,但关键字参数之间是不存在先后顺序的。

例4:

def my_sum(a=7, b):   # 现在我将默认参数放在位置参数的前面,我们看看有什么报错?
    res = a + b
    print('a: ', a)
    print('b: ', b)
    return res


ret = my_sum(1)

print(ret)

结果截图:

python 位置参数,默认参数 python函数参数位置_默认参数

我们看到这个语法错误的意思:非默认参数跟在默认参数之后。也就是说位置参数是在默认参数之后了,更进一步说默认参数写在位置参数前面了。

6、默认参数的值是在函数定义阶段赋值的,准确地说被赋予的是值的内存地址。

例5:

a = 7

def func(x, y=a):   # y 赋予的是7的内存地址
    print(x, y)

a = 8
func(1)

结果:

python 位置参数,默认参数 python函数参数位置_默认参数_02

例6:

a = [1, 3]


def func(x, y=a):    # y 被赋予[1, 3]的内存地址
    print(x, y)


a.append(9)
func(1)

 结果:

python 位置参数,默认参数 python函数参数位置_python_03

7、默认值可以被指定为任意数据类型,但是最好不要使用可变类型,函数最理想的状态:函数的调用只跟函数本身有关系,不受外界代码的影响。

例7:

def func(x, y, z, l=None):
    if l is None:
        l = []
    l.append(x)
    l.append(y)
    l.append(z)
    print(l)


func(1, 2, 3)
func(11, 22, 33)
list_1 = [111, 222]
func(1, 2, 3, list_1)

8、可变参数:

定义函数的时候,我们不确定调用的时候会传递多少个参数(不传参也可以),此时,可用包裹packing位置参数或者包裹关键字参数,来进行参数传递,会显得非常方便。

8.1 包裹位置传递:

def my_sum(*args):
    sum = 0
    for i in args:
        sum = sum + i
    return sum


print(my_sum(1, 2))
print(my_sum(1, 2, 3))
print(my_sum(1, 2, 3, 4))

结果:

python 位置参数,默认参数 python函数参数位置_元组_04

我们传递的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包位置传递。

如果将def my_sum(*args) 换成 def my_sum(*a) ,也是可以的,使用a来代替args。

之所以叫args,这种一种习惯:

python 位置参数,默认参数 python函数参数位置_赋值_05

我们再看一个例子:

def func(*args): # 站在形参的角度上,给变量加上*,就是组合传来的值。
    print(args)


func(1, 2, 3, 4, 5)

l = [1, 2, 3, 4, 5]
func(*l)    #站在实参的角度上,给一个序列加上*, 就是将这个序列按照顺序打散。

注意:两个星号的作用,有“组合”和“打散”的作用。

8.2 包裹关键字传递:

def func(**kwargs):
    print(kwargs)


print(func(a=1))
print(func(a=1, b=2, c=3))

kargs是一个字典(dict),搜集所有关键字参数。

那么可以将两者结合起来:

def func(*args, **kwargs):
    print(args, kwargs)


print(func(1, 2, 3, 4 = 'good', 5 = 'best')

我们再看一个例子:

def func(**kwargs):
    print(kwargs)


func(a=1, b=2)
d = {'a': 1, 'b': 2}
print(func(**d))

看看这个两个星号**的作用。也是“组合”和“打散”的作用。

9、解包裹参数:

*args和**kwargs, 也可以在函数调用的时候使用,称之为解包(unpacking)。

9.1 在传递元组的时候,让元组的每一个元素对应一个位置参数:

def print_hello(name, sex):
    print(name, sex)


args = ('tanggu', '男')
print_hello(*args)

2、在传递字典的时候,让字典的每个键值对作为一个关键字参数传递给函数。

def print_hello(**kwargs):
    print(kargs)


kargs = {'name': 'tanggu', 'sex': u'男'}

print_hello(**kwargs)

10、位置参数、默认参数和可变参数的混合使用:

10.1 规则:先位置参数、*args, 默认参数、**kwargs。

11、函数的注释:

11.1 可以给代码加行注释;

11.2 使用三引号,里面写函数的功能、参数说明和返回值说明。我们看下一个函数的注释:

python 位置参数,默认参数 python函数参数位置_默认参数_06

 这是一个非常标准的函数注释。