Python中函数的各种类型参数详解

Python中函数的参数类型非常丰富多彩。

Python的函数支持的参数类型包括:

(1)位置参数

(2)默认参数

(3) 可变参数

(4)关键字参数

(5)命名关键字参数

接下来,我们一一来学习一下:

(1)位置参数

位置参数,就是普通的参数。写在函数名后的小括号中,如下面例子:

def power(x):
    return x * x
def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

(2)默认参数

默认参数允许函数设置参数的默认值。例如:

def power(x, n = 2):......

其中参数n的默认值为2,调用函数时,可以省略这个参数,如:power(5),这里的5会赋值给x。

注意事项:

1.必选参数在前,默认参数在后。

Why?因为Python中函数的实际参数与形式参数的匹配顺序是从左至右的。

2.如何设置默认参数?

变化大的参数放前面,变化小的参数放后面当默认的参数。

降低函数调用的难度。

例如:在某校的学生信息管理系统中,可以把年龄和城市设为默认参数(因为都在一个城市,同年级的年龄也大都相同)。

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

3.可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。

如:

enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')

4.一个默认参数的大坑。

先定义一个函数,传入一个list,添加一个END再返回.

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

试着用默认参数,连续执行add_end?

你会发现,似乎函数每次都“记住了”上次添加了’END’后的list。

原因是:

Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。

默认参数强烈建议指向不变对象!可以用None这个不变对象来实现。

def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L

如果可以设计一个不变对象,那就尽量设计成不变对象。

3.可变参数

参数个数不确定,可以用list和tuple来充当参数,但是需要现行构造。

形式:

        在参数名字前加 “*”号。

调用时可传入任意个(包括0个)参数。

可变参数在调用时自动组装为一个tuple

list参数和tuple参数前加“*”可作为可变参数使用。

接下来,我们用例子来学习一下可变参数的用法。

需求:计算a^2+b^2+c^2+......

利用list或tuple为参数,可实现如下代码:

def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84

但是用户在调用函数时,需要事先构造好一个list或tuple的数据集。

如果是用可变参数,用户可以直接输入数据集,用逗号隔开,并且数据个数无硬性限制。

def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

>>> calc(1, 2)
5
>>> calc()
0

在调用具有可变参数的函数时,可以利用list或tuple前加星号的形式来充当可变参数实参。

如:

>>> nums = [1, 2, 3]
>>> calc(*nums)
14

4.关键字参数

关键字参数扩展函数的功能。 允许你传入0个或任意个含参数名的参数,在函数内部自动组装为一个dict

如:

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

>>> person('Michael', 30)
name: Michael age: 30 other: {}

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}

>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

一个dict参数可以当成一个关键字参数

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

注意:person函数内部对extra的改变是改变的extra的副本,对extra这个dict本身并没有做出改变。

试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。

可变参数和关键字参数使用时机和形式

可变参数

        定义函数时,形式参数+‘*’,表示可变参数,使用时,直接输入可变数量的参数

        使用函数时,实际参数+‘*’,实际参数本身必须是一个list或者touple。

关键字参数

        定义函数时,形式参数+‘**’,表示关键字参数,使用时,直接以“键=‘值’”的形式输入

        使用函数时,实际参数+‘**’,实际参数本身必须是一个dict

5.命名关键字参数

命名关键字参数:限制关键字参数的名字。例如:接收city和job作为关键字参数。

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

一个特殊分隔符“*”,*后面的参数被视为命名关键字参数。

>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:

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

命名关键字参数必须传入参数名,否则报错

命名关键字参数可以有缺省值

def person(name, age, *, city='Beijing', job):
    print(name, age, city, job)
>>> person('Jack', 24, job='Engineer')
Jack 24 Beijing Engineer

6.参数的组合

在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。

参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

7.练习

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(1,2)
f1(1,2,3)
f1(1,2,3,'a','b')
f1(1,2,3,'a','b',x = 99)
f2(1,2,3,d = 'aaa',ext = None)
args = (1,2,3,4)
kw = {'d':99,'x':'#'}
f1(*args,**kw)
args = (1,2,3)
kw = {'d':99,'x':'#'}
f2(*args,**kw)

答案:

a = 1 b = 2 c = 0 args =  () kw =  {}
a = 1 b = 2 c = 3 args =  () kw =  {}
a = 1 b = 2 c = 3 args =  ('a', 'b') kw =  {}
a = 1 b = 2 c = 3 args =  ('a', 'b') kw =  {'x': 99}
a = 1 b = 2 c = 3 d =  aaa kw =  {'ext': None}
a = 1 b = 2 c = 3 args =  (4,) kw =  {'d': 99, 'x': '#'}
a = 1 b = 2 c = 3 d =  99 kw =  {'x': '#'}

8.参数组合

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

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

例如:

#以下函数允许计算两个数的乘积,请稍加改造,变成可接收一个或多个数并计算乘积
def product(x, y):
    return x * y

测试程序如下:

print('product(5) =', product(5))
print('product(5, 6) =', product(5, 6))
print('product(5, 6, 7) =', product(5, 6, 7))
print('product(5, 6, 7, 9) =', product(5, 6, 7, 9))
if product(5) != 5:
print('测试失败!')
elif product(5, 6) != 30:
	print('测试失败!')
elif product(5, 6, 7) != 210:
	print('测试失败!')
elif product(5, 6, 7, 9) != 1890:
	print('测试失败!')
else:
	try:
		product()
		print('测试失败!')
	except TypeError:
		print('测试成功!’)

答案:


def product(x, *num):
    for n in num:
        x = x * n
    return x

9.参数解包(拆包)

传递实参时,可以在序列类型的参数前添加星号,这样他会自动将序列中的元素依次作为参数传递。

例如:

def fn1(a,b,c):
    print(a, b, c)

x = (1,2,3) # 元组数据
y = [4,5,6] # 列表数据
z = {'a':7, 'b':8, 'c':9} # 字典数据

fn1(*x)  # 元组解包  *
fn1(*y)  # 列表解包  *
fn1(**z) # 字典解包  通过 **对字典进行解包

# 输出为
1 2 3
4 5 6
7 8 9

学会了就点个赞吧。

你可能感兴趣的:(Python程序设计教程,python,开发语言)