pyhon内置了很多函数,比如 max,abs,sorted,int,str,bool等等
我们可以对这些函数取别名操作:
a = abs # 变量a指向abs函数 ,注意,别写括号,写了括号就成了执行此函数
print(a(-5)) # 输出5
python函数可以返回多个值,返回多个值的时候,是返回的一个tuple元组。
def move(a, b, c, base=0):
x = a + b
y = b + c - base
return x, y
print(move(1, 5, 8, 7)) # (6, 6)
默认参数:
函数参数如果写了名字加等式,那么传参的时候也写名字的话,位置可以随便换,但是,如果你传参的时候不写名字,那么必须按顺序,
比如下面这个函数,我只传个x进来,就返回平方,传了n进来,那么就计算n次方,我们也可以把n默认值改成其他的。
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
但是默认参数也有坑,先定义一个函数,传入一个list,添加一个END再返回:下面连续调用print(add_end())时,就会累加了,出现问题。
def add_end(L=[]):
L.append('END')
return L
# 当正常传进一个list的时候是正常的
print(add_end(L=[1,5])) # [1, 5, 'END']
print(add_end(L=[1,5])) # [1, 5, 'END']
print(add_end(L=[1,5])) # [1, 5, 'END']
# 调用时不传参的时候,第一次看是正常的。之后就出现累加情况
print(add_end()) # ['END']
print(add_end()) # ['END', 'END']
print(add_end()) # ['END', 'END', 'END']
# 传入一个空的list也是正常的
print(add_end(L=[]))
print(add_end(L=[]))
print(add_end(L=[]))
所以,如果想避免这种累加情况,就调用时写 print(add_end(L=[])),或者函数写这样,如果不传参进来,我就为None,那么就报错。
def add_end(L=None):
默认函数就是,你不传这个参数,我就用默认的值,
def mr(a, b, a1=2, b1=5): # 函数中,a和b为必传参且传参位置不能变,a1,b1为默认参且如果传参时写明等式传参位置就可变,且可传可不传,
print(a, b, a1, b1)
mr(5, 6, b1=4, a1=7)
mr(5, 6, 4, b1=7)
可变参数
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。且可变参数传进来是变成了一个元组
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全没啥区别。
def calc(*numbers):
print('numbers:',numbers)
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calc())
print(calc(1, 2))
print(calc(1, 2,3,4))
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:calc(nums[0], nums[1], nums[2])
这种写法当然是可行的,问题就是太繁琐,所以Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:
nums = [1, 2, 3]
calc(*nums) # *nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见。
关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('Michael', 30)
person('Bob', 35, city='Beijing')
person('Adam', 45, gender='M', job='Engineer')
# person('Adam', 45, 'Engineer') 这样就报错,结论:必须写成字典格式,也可以直接扔一个字典进去
关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求
命名关键字参数
和关键字参数有点不同,关键字参数接收传进来随意名字的参数。
而命名关键字参数,是在函数定义的时候就写好了参数名
def person(name, age, *, city = 'Beijing', job): # 如果没写默认值,就必须传进来
print(name, age, city, job)
# 和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
person('Jack', 24, job='Engineer')
# 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
person('Jack', 24, *[5,8],city='Beijing', job='Engineer')
# 命名关键字参数可以有缺省值,从而简化调用:
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
person('Jack', 24, job='Engineer')
总结:
在Python中定义函数,可以用位置参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
必选参数:也就是位置参数,最初始的
默认参数:def person(name, age, city = '四川', job='厨师'):
可变参数:def person(*name): 可变是进来成元组,不能传参数名字,因为没用参数名接收
关键字参数:def person(**name):进来成字典,所以必须参数名
命名关键字参数:def person(name,age,*,city ,job): or def person(name, age, *args, city, job):
def person(name, age, *, city='Beijing', job):这种就是有默认值,可以不传,同理默认参数
# 在函数调用的时候,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(1, 2) # a = 1 b = 2 c = 0 args = () kw = {}
f1(1, 2, c=3) # a = 1 b = 2 c = 3 args = () kw = {}
f1(1, 2, 3, 'a', 'b') # a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
f1(1, 2, 3, 'a', 'b', x=99) # a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
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': 88, 'x': '#'}
f2(*args, **kw) # a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}
所以,对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。
注意:虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差。