专栏首页祥的专栏[Python]函数的各种传参

[Python]函数的各种传参

原创文章

文章目录
  • @[toc]

  • 0. 环境
  • 1. 位置参数
  • 2. 默认参数
  • 3. 可变参数
    • 3.1. 用法
    • 3.2. 简洁调用方法
  • 4. 关键字参数
    • 4.1. 用法
    • 4.2. 简洁调用方法
    • 4.3. 检查关键字参数
  • 5. 命名关键字参数
    • 5.1. 用法
    • 5.2.. 特殊情况
  • 6. 组合参数
  • 7. 参考文献

Python函数的各种传参

0. 环境

  • python3.6

1. 位置参数

没什么好说的,和C++语言都一样,不过调用起来有点方便,就以幂运算为例吧。

# x是底数,n为幂次
def power(x, n):
    ret = 1
    while n > 0:
        n = n - 1
        ret = ret * x

    return ret

调用函数的时候,一个萝卜一个坑,按部就班就ok了

>> power(3,2)
>> 9

2. 默认参数

# x是底数,n为幂次(默认函数执行平方运算)
def power(x, n=2):
    ret = 1
    while n > 0:
        n = n - 1
        ret = ret * x

    return ret
>> power(3)
9
>>

这也和C++中定义函数一样,可以在声明中设置默认参数,不过要注意的是:

必须设定参数在前(如函数中的底数x),默认参数(如函数中的幂次n)在后,否则Python的解释器会报错

这样做的好处是什么?当然是调用起来省事啦,懒惰才是第一生产力!

注意:

设定默认参数时,默认值必须是一个不变的对象,比如说上述例子中n=2中的2

3. 可变参数

3.1. 用法

编写一个函数sum()可以计算传入变量的和。

def sum(*numbers):
    ret = 0
    print(type(numbers))  # 测试参数类型
    for n in numbers:
        ret = ret + n
    return ret
>> print(sum(1, 2, 3, 4, 5))
<class 'tuple'>
15
>> print(sum())
<class 'tuple'>
0
>>

可以看出,在定义函数时,在参数前面加入一个*,就可以使得函数内部得到一个tuple数组。

3.2. 简洁调用方法

如果已经有了一个list或是tuple,要传入一个有可变参数的函数,有两种方法。

  • 方法1:list或是tuple用下标,一个一个传入(麻烦
  • 方法2: 在传入参数(list或是tuple)的变量名前加*(有点类似C语言指针的用法,自己体会一下吧)
>> ns = [1, 2, 3]
# 方法1(麻烦)
>> sum(ns[0], ns[1], ns[2])


# 方法2(推荐)
>> sum(*ns)

4. 关键字参数

4.1. 用法

  • 可变参数 允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple
  • 关键字参数 允许你传入0个或任意个参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def car(brand, price, **kw):
    print("brand: ", brand)
    print("price: ", price)
    print("kw: ", kw)
    print("type(kw): ", type(kw))
# 情况1
>> car('Volkswagen', '9999')
brand:  Volkswagen
price:  9999
kw:  {}
type(kw):  <class 'dict'>
>> 

# 情况2
>> car('Volkswagen', '9999', place='Germany', salePlace='China')
brand:  Volkswagen
price:  9999
kw:  {'place': 'Germany', 'salePlace': 'China'}
type(kw):  <class 'dict'>
>> 

4.2. 简洁调用方法

类似3.2节,如果已经有了一个字典dict,可以在调用函数时把它当做关键字参数传入进入,只需要在前面变量名前加**

>> extraParam = {'place': 'Germany', 'salePlace': 'China'}
>> car('Volkswagen', '9999', **extraParam)
brand:  Volkswagen
price:  9999
kw:  {'place': 'Germany', 'salePlace': 'China'}
type(kw):  <class 'dict'>
>> 

4.3. 检查关键字参数

其实就是检查字典dict

def car(brand, price, **kw):
    print("brand: ", brand)
    print("price: ", price)
    print("kw: ", kw)
    print("type(kw): ", type(kw))
    
    # 检查代码
    if 'place' in kw:
    	# 有place这个参数
    	pass
    if 'salePlace' in kw:
    	# 有salePlace这个参数
    	pass

5. 命名关键字参数

5.1. 用法

如果要 限制 关键字参数名字,就可以用 命名关键字参数,例如,只接收placesalePlace作为 关键字参数。这种方式定义的函数如下所示:

def car2(brand, price, *, place, salePlace):
    print("brand: ", brand)
    print("price: ", price)
    print("place: ", place)
    print("salePlace: ", salePlace)
    print("type(place): ", type(place))
    print("type(salePlace): ", type(salePlace))

和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符**后面的参数被视为命名关键字参数

运行情况:

# 情况1
>> car2('Volkswagen', '9999', place='Germany', salePlace='China')
brand:  Volkswagen
price:  9999
place:  Germany
salePlace:  China
type(place):  <class 'str'>
type(salePlace):  <class 'str'>

# 情况2
>> car2('Volkswagen', '9999', 'Germany', 'China')
Traceback (most recent call last):
    car2('Volkswagen', '9999', 'Germany', 'China')
TypeError: car2() takes 2 positional arguments but 4 were given

# 情况3
>> car2('Volkswagen', '9999', salePlace='China')
Traceback (most recent call last):  
    car2('Volkswagen', '9999', salePlace='China')
TypeError: car2() missing 1 required keyword-only argument: 'place'

# 情况4
>> car2('Volkswagen', '9999', place='Germany', salePlace='China', city = 'beijing')
Traceback (most recent call last):
    car2('Volkswagen', '9999', place='Germany', salePlace='China', city = 'beijing')
TypeError: car2() got an unexpected keyword argument 'city'

解释:

  • 情况1: 一般调用方式;
  • 情况2: 因为调用时缺少参数名placesalePlacePython解释器把这4个参数均视为位置参数,但car2()函数仅接受2位置参数
  • 情况3: 由于没有设置默认值,所以命名关键字参数不可以省略;
  • 情况4: 没有定义city这个命名关键字参数

注意: 命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错,如情况2所示。

针对情况3出现的问题,只需要设置好参数的默认值就可以避免了:

def car2(brand, price, *, place='', salePlace=''):
    print("brand: ", brand)
    print("price: ", price)
    print("place: ", place)
    print("salePlace: ", salePlace)
    print("type(place): ", type(place))
    print("type(salePlace): ", type(salePlace))
# 情况1
>> car2('Volkswagen', '9999')
brand:  Volkswagen
price:  9999
place:  
salePlace:  
type(place):  <class 'str'>
type(salePlace):  <class 'str'>


# 情况2
>> car2('Volkswagen', '9999', salePlace='China')
brand:  Volkswagen
price:  9999
place:  
salePlace:  China
type(place):  <class 'str'>
type(salePlace):  <class 'str'>

5.2… 特殊情况

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

def car3(brand, price, *args, place='', salePlace=''):
    print("brand: ", brand)
    print("price: ", price)
    print("args: ", args)
    print("place: ", place)
    print("salePlace: ", salePlace)

    print("type(args): ", type(args))
    print("type(place): ", type(place))
    print("type(salePlace): ", type(salePlace))

运行情况:

# 将place参数省略,使用默认参数
>> car3('Volkswagen', '9999', 1, 2, 3, salePlace='China')
brand:  Volkswagen
price:  9999
args:  (1, 2, 3)
place:  
salePlace:  China
type(args):  <class 'tuple'>
type(place):  <class 'str'>
type(salePlace):  <class 'str'>

注意:

使用命名关键字参数时,如果没有可变参数,就必须加一个*作为特殊分隔符。如果缺少*,Python解释器将其视为位置参数

6. 组合参数

在Python中定义函数,可以用必选参数默认参数可变参数关键字参数命名关键字参数,这5种参数都可以组合使用。 注意: 参数定义的顺序必须是:必选参数默认参数可变参数命名关键字参数关键字参数

我的建议是:别乱搞,函数接口理解性变差,损人不利己。

7. 参考文献

廖雪峰Python教程:https://www.liaoxuefeng.com/wiki/1016959663602400/1017261630425888


OK! 以上,Enjoy~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 装饰器实现用户验证登录

    在实现用户验证的登录的时候可以使用装饰器工厂产生装饰器,让装饰器得到参数,从而判断登录类型,并验证用户登录条件,代码实现如下:

    skylark
  • C++服务器开发之笔记三

    为什么需要原子性操作? 我们考虑一个例子: (1)x++这个常见的运算符在内存中是怎样操作的? 从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x所处的内...

    用户1198337
  • Go语言中反射的正确使用

    介绍 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型。 反射有两个问题...

    李海彬
  • Go语言中反射的正确使用

    介绍 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型。 反射有两个问题...

    李海彬
  • Python编程思想(29):使用type()函数定义类

    李宁老师已经在「极客起源」 微信公众号推出《Python编程思想》电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法。读者可以在「极客...

    蒙娜丽宁
  • Python面试题之Python中type和object的关系

    下面是jeff kit的回答: 给别人讲解过很多次,但写成文字是第一次。试一试吧,自己主要也是看了这篇文章(Python Types and Objects...

    Jetpropelledsnake21
  • Go语言中反射的正确使用

    介绍 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型。 反射有两个问题...

    李海彬

扫码关注云+社区

领取腾讯云代金券