python:函数中五花八门的参数形式(茴香豆的『回』字有四种写法)

简介: 毫不夸张的说,python语言中关于函数参数的使用,是我见过最为灵活的,随便怎么玩都可以,本文以数学乘法为例,演示几种不同的传参形式: 一、默认参数 def multiply1(x, y): return x * y print("multiply1:", multiply1(2, 3)) 输出 multiply1: 6  ,这是最平淡无奇的函数写法。

毫不夸张的说,python语言中关于函数参数的使用,是我见过最为灵活的,随便怎么玩都可以,本文以数学乘法为例,演示几种不同的传参形式:

一、默认参数

def multiply1(x, y):
    return x * y


print("multiply1:", multiply1(2, 3))

输出 multiply1: 6  ,这是最平淡无奇的函数写法。

python支持默认参数,比如:如果想让1个数自动乘10,又不想定义新的函数,上面的代码,可以改成:

def multiply1(x, y=10):
    return x * y


print("multiply1:", multiply1(2, 3))
print("multiply1:", multiply1(2))

输出

multiply1: 6
multiply1: 20

另外,调用函数时,除了按顺序依次给值外,还可以“显式”的命名传值,示例如下:

print("multiply1:", multiply1(x=2, y=4))
print("multiply1:", multiply1(y=3, x=5))
print("multiply1:", multiply1(x=4))

输出:

multiply1: 8
multiply1: 15
multiply1: 40

显式指定参数名称后,顺序就不重要了。

 

二、可变参数(tuple)

如果乘数多于2个,上面的版本显然不能满足要求,可以参考下面的版本:

def multiply2(*numbers):
    result = 1
    for i in numbers:
        result *= i
    return result


print("multiply2(1):", multiply2(1, 2, 3))
test = (1, 2, 3)
print("multiply2(2):", multiply2(*test))
print("multiply2(3):", multiply2(test))

参数前加一个*,就表示参数个数不固定(其实python是当作tuple来看待),上面的代码会输出:

multiply2(1): 6
multiply2(2): 6
multiply2(3): (1, 2, 3) #注意这一行,如果是一个已经定义好的tuple变量,想传入可变参数中调用,必须前加*,否则的话,程序不报错,但不是你期望的结果

当可变参数与默认参数结合在一起时,有一个地方需要注意:

def multiply2_2(*numbers, base=10):
    result = 1
    for i in numbers:
        result *= i
    return result * base


print("multiply2_2:", multiply2_2(1, 2, 3, base=10))

输出:

multiply2_2: 60 

这很好理解,但如果在前面再加一个默认参数:

def multiply2_3(x=2, *numbers, base=10):
    print("x=", x, ",numbers:", numbers, ",base:", base)
    result = 1
    for i in numbers:
        result *= i
    return x * result * base


print("multiply2_3(1):", multiply2_3(4, 1, 2, base=10))
print("multiply2_3(2):", multiply2_3(4, *(1, 2), base=10))
print("multiply2_3(3):", multiply2_3(*(1, 2), base=10))
# print("multiply2_3(4):", multiply2_3(x=4, *(1, 2), base=10))  # 这里会报错

输出:

x= 4 ,numbers: (1, 2) ,base: 10
multiply2_3(1): 80
x= 4 ,numbers: (1, 2) ,base: 10
multiply2_3(2): 80
x= 1 ,numbers: (2,) ,base: 10
multiply2_3(3): 20

注意:multiply2_3(*(1, 2), base=10) 这行调用时,(1,2)这个tuple里的第1个元素实际上是给到x了,从输出就能印证,函数定义中的x=2默认值,并没有起到作用

如果把最后一行 print("multiply2_3(4):", multiply2_3(x=4, *(1, 2), base=10)) 的注释去掉,运行会报错:

print("multiply2_3(4):", multiply2_3(x=4, *(1, 2), base=10)) # 这里会报错
TypeError: multiply2_3() got multiple values for argument 'x'

原因在于(1,2)的第1个元素会赋值给x,然后又指定了x=4,所以python会认为参数x有2个值1、4,不知道该用哪个,只好蒙逼报错。

 

三、字典参数(dic)

如果在参数前加2个*,就变成字典(key-value)参数了,参考下面的示例:

def multiply3(**numbers):
    result = 1
    for a in numbers:
        result *= numbers[a]
    return result


dic1 = {"a": 1, "b": 2, "c": 3}
print("multiply3(1):", multiply3(**dic1))
print("multiply3(2):", multiply3(**{"a": 1, "b": 2, "c": 3}))
print("multiply3(3):", multiply3(a=1, b=2, c=3))

注意调用的姿势,有好几种姿势可解锁~_^ 输出如下:

multiply3(1): 6
multiply3(2): 6
multiply3(3): 6

可能有同学感觉dic参数太灵活,单从调用参数的“长相”上,几乎就是一个json串,随便传,太浪了! 有没有什么办法约束一下,比如:要求dic字典中,只能包含指定的key。办法当然有:

def multiply4(*, a, b):
    return a * b


print("multiply4:", multiply4(**{"a": 2, "b": 3}))
print("multiply4:", multiply4(a=2, b=3))
print(multiply4(**{"a": 2, "b": 3, "c": 1}))

注意写法:*,a,b 表示该函数接受dic字典参数,但是dic中的key名称,只能是"a" , "b",输出:

multiply4: 6
multiply4: 6

Traceback (most recent call last):
File ".../03.py", line 42, in <module>
print(multiply4(**{"a": 2, "b": 3, "c": 1}))
TypeError: multiply4() got an unexpected keyword argument 'c'

即:最后一行调用print(multiply4(**{"a": 2, "b": 3, "c": 1}))时,这里出现了一个不守约定的key名:c ,所以报错了

当然,也可以配合默认参数,做些变化,比如:想给乘法结果设置一个基数。

def multiply5(base, *, a=1, b):
    return base * a * b


print("multiply5(1):", multiply5(10, **{"a": 2, "b": 3}))
print("multiply5(2):", multiply5(10, b=3))

输出:

multiply5(1): 60
multiply5(2): 30

 

四、大乱炖

如果把上面的各种奇淫技巧结合起来,就蛮头晕了,强烈不推荐!

def multiply6(a, b, c=1, *d, e=1, f):
    print("a=", a, ",b=", b, ",c=", c, ",d=", d, ",e=", e, ",f=", f)
    result = a * b * c
    for i in d:
        result *= i
    result *= (e * f)
    return result


print("multiply6(1):", multiply6(1, 2, (3, 4, 5), f=6))
print("multiply6(2):", multiply6(1, 2, *(3, 4, 5), f=6))
print("multiply6(3):", multiply6(1, 2, 3, *(4, 5, 6), e=7, f=8))

输出:

a= 1 ,b= 2 ,c= (3, 4, 5) ,d= () ,e= 1 ,f= 6
multiply6(1): (3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5)
a= 1 ,b= 2 ,c= 3 ,d= (4, 5) ,e= 1 ,f= 6
multiply6(2): 720
a= 1 ,b= 2 ,c= 3 ,d= (4, 5, 6) ,e= 7 ,f= 8
multiply6(3): 40320

tips: 首次调用故意少写了一个*,于是(3,4,5)这个元组就被乘了2*6次,变成了3,4,5连续重复12次。

def multiply7(a, b=10, *c, **d):
    print("a=", a, ",b=", b, ",c=", c, ",d=", d)
    result = a * b
    for i in c:
        result *= i
    for j in d:
        result *= d[j]
    return result


print("multiply7(1):", multiply7(2, *(3, 4), **{"x": 5, "y": 6}))
print("multiply7(2):", multiply7(2, *(3, 4), x=5, y=6))
print("multiply7(3):", multiply7(2, 3, 4, x=5, y=6))
print("multiply7(4):", multiply7(2, 3, 4, 5, 6))

输出:

a= 2 ,b= 3 ,c= (4,) ,d= {'x': 5, 'y': 6}
multiply7(1): 720
a= 2 ,b= 3 ,c= (4,) ,d= {'x': 5, 'y': 6}
multiply7(2): 720
a= 2 ,b= 3 ,c= (4,) ,d= {'x': 5, 'y': 6}
multiply7(3): 720
a= 2 ,b= 3 ,c= (4, 5, 6) ,d= {}
multiply7(4): 720

虽然看上去,调用方式各式各样,但是结果全是720,而且函数定义中的b=10,这个默认值完全不起作用。

 

五、多返回值

前面提到的都是入参的各种姿势,在函数返回结果上,python也有过人之处,可以一次返回多个元素:

def swap(x, y):
    return y, x


a, b = swap(1, 2)
print(a, b)

result = swap(1, 2)
print(type(result), result)

输出:

2 1
<class 'tuple'> (2, 1)

tips: 多个返回值,只是假象,其实返回的是一个tuple对象。

 

参考文档:

python 函数的参数

作者: 菩提树下的杨过
出处: http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
目录
相关文章
|
7天前
|
缓存 监控 程序员
Python中的装饰器是一种特殊类型的声明,它允许程序员在不修改原有函数或类代码的基础上,通过在函数定义前添加额外的逻辑来增强或修改其行为。
【6月更文挑战第30天】Python装饰器是无侵入性地增强函数行为的工具,它们是接收函数并返回新函数的可调用对象。通过`@decorator`语法,可以在不修改原函数代码的情况下,添加如日志、性能监控等功能。装饰器促进代码复用、模块化,并保持源代码整洁。例如,`timer_decorator`能测量函数运行时间,展示其灵活性。
16 0
|
12天前
|
Python
python之print函数
python之print函数
15 0
|
2天前
|
Python
|
2天前
|
Python
python解包字典到函数参数
【7月更文挑战第5天】
6 2
|
14天前
|
测试技术 开发者 Python
Python中的装饰器:提升函数的灵活性和可重用性
在Python编程中,装饰器是一种强大的工具,它可以在不修改函数本身的情况下,动态地扩展函数的功能。本文将介绍装饰器的工作原理及其在实际开发中的应用,帮助读者更好地理解和利用这一特性。
|
11天前
|
分布式计算 算法 Python
Python函数进阶:四大高阶函数、匿名函数、枚举、拉链与递归详解
Python函数进阶:四大高阶函数、匿名函数、枚举、拉链与递归详解
|
13天前
|
存储 Python
在Python中,匿名函数(lambda表达式)是一种简洁的创建小型、一次性使用的函数的方式。
【6月更文挑战第24天】Python的匿名函数,即lambda表达式,用于创建一次性的小型函数,常作为高阶函数如`map()`, `filter()`, `reduce()`的参数。lambda表达式以`lambda`开头,后跟参数列表,冒号分隔参数和单行表达式体。例如,`lambda x, y: x + y`定义了一个求和函数。在调用时,它们与普通函数相同。例如,`map(lambda x: x ** 2, [1, 2, 3, 4, 5])`会返回一个列表,其中包含原列表元素的平方。
26 4
|
13天前
|
Python
在Python中,高阶函数是指那些可以接受一个或多个函数作为参数,并返回一个新的函数的函数。
【6月更文挑战第24天】Python的高阶函数简化代码,增强可读性。示例:`map()`检查用户名合法性,如`[&quot;Alice&quot;, &quot;Bob123&quot;, &quot;Charlie!&quot;, &quot;David7890&quot;]`;`reduce()`与`lambda`结合计算阶乘,如1到10的阶乘为3628800;`filter()`找出1到100中能被3整除的数,如[3, 6, 9, ..., 99]。
19 3
|
14天前
|
分布式计算 大数据 调度
MaxCompute产品使用问题之为什么用python写的udf函数跑起来比本地还要慢
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
14天前
|
SQL 分布式计算 大数据
MaxCompute产品使用问题之建了一个python 的 UDF脚本,生成函数引用总是说类不存在,是什么导致的
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。