专栏首页快乐学PythonPython 优雅的使用参数 - 可变参数(*args & **kwargs)

抱歉,你查看的文章已删除

Python 优雅的使用参数 - 可变参数(*args & **kwargs)

写在前面的话

传递参数的行为对于现在编程语言来说,再寻常不过的概念

参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。 - 来自 wikipedia

先来看一个例子:

# 来源于 https://docs.python.org/2/library/itertools.html
def chain(*iterables):
    for it in iterables:
        for element in it:
            yield element

大家可能注意到 *iterables 了,对了,就是他, 不定参数

>>> from itertool import chain
>>> chan([1,2], [2, 3])             # 你可以这么用
[1, 2, 2, 3]
>>> chan([1,2], [2, 3], [4, 5])     # 你还可以这么用
[1, 2, 2, 3, 4, 5]
>>> chan([1,2], [2, 3], [4, 5])     # 你也可以这么用
[1, 2, 2, 3, 4, 5]
... // 随心所欲的加参数

很神奇把,(_)v,来讲讲枯燥的概念把!

可能很多人用了几年的 Python 都没真正使用过可变参数,就比如我,为了学写通用模块,就会对它有需求;或许你经常看 Python 模块库代码,会发现很多函数的参数定义,都会跟上 *args**kwargs(不定参数的另一种形式,后面会讲到)。

在计算机程序设计,一个可变参数函数是指一个函数拥有不定引数,即是它接受一个可变量目的参数。 - 来自 wikipedia

通俗的说就是,函数可以处理不同数量的参数。

在我看来,几乎80%的使用可变参数列表的场景,都可以使用数组和字典来解决。但是使用可变参数列表的函数可以提供一种数组和字典无法提供的东西:优雅

*args

def argsFunc(a, *args):
    print a
    print args
    
>>> argsFunc(1, 2, 3, 4)
1
(2, 3, 4)

argsFunc 中匹配完定义好的参数,剩余的参数以元组的形式存储在 args(args 名称你可以自行定义),因此在上述程序中只要你传入不小于 1 个参数,该函数都会接受,当然你也可以直接定义只接受可变参数,你就可以自由传递你的参数:

def argsFunc(*my_args):
    print my_args
    
>>> argsFunc(1, 2, 3, 4)
(1, 2, 3, 4)
>>> argsFunc()
()

很简单把,现在来将另一个种不定参数形式

**kwargs

形参名前加两个*表示,参数在函数内部将被存放在以形式名为标识符的 dictionary 中,这时调用函数的方法则需要采用 arg1=value1,arg2=value2 这样的形式。

为了区分,我把 args 称作为数组参数,*kwargs 称作为字典参数

>>> def a(**x):print x
>>> a(x=1,y=2,z=3)
{'y': 2, 'x': 1, 'z': 3} #存放在字典中

不过,有个需要注意,采用 **kwargs 传递参数的时候,你不能传递数组参数

>>> a(1,2,3) #这种调用则报错
Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
TypeError: a() takes exactly 0 arguments (3 given)

同样很简单,但是我们什么时候可以用到他呢?

import mysql.connector  

db_conf = {
    user='xx',
    password='yy', 
    host='xxx.xxx.xxx.xxx',
    database='zz'
}

cnx = mysql.connector.connect(
    user=db_conf['user'],
    password=db_conf['password'], 
    host=db_conf['host'],
    database=db_conf['database']
    )
...

相比,使用 Mysql Python 库时候,经常看到这个样子的代码,db_conf 一般都从配置文件读取,这是优雅的不定字典参数就派上用途了!

import mysql.connector  

db_conf = {
    user='xx',
    password='yy', 
    host='xxx.xxx.xxx.xxx',
    database='zz'
}

cnx = mysql.connector.connect(**db_conf)
...

怎样,是不是顺眼多了,代码也省了不少!_

今天就到这里了,很早就开始写这一篇了,不想像网路上的大部分博客,只是写一个使用文档类型的教程,看完就忘了。

适当的考虑应用场景,希望能印象深刻。学会,就尽可能的使用它;再优雅的概念,不用也是百搭。

请记得点赞和分享这篇文章让更多的人看到它!另外,记得关注我的简书号马哥学Python,这样你就不会错过任何有价值的文章!

我会阅读所有的评论,所以无论你有什么想要说的,或者是想要分享的,甚至是问题之类的,都可以在下面留言。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 对mysql left join 出现的重复结果去重

    简单说明问题出现的原因: MySQL left join 语句格式为: A LEFT JOIN B ON 条件表达式

    马哥Python
  • django-haystack ImportError: cannot import name 'six' from 'django.utils' in django 3.x

    原因是从django 3.x起去掉了django.utils里的six包 网上一搜全是说下载six.py, 然后复制进site-package下的django...

    马哥Python
  • MySQL中索引的限制

    下面列出了目前 MySQL中与索引使用相关的限制 (1)MyISAM存储引擎索引键长度的总和不能超过1000字节 (2)BLOB和TEXT类型的列只能创建前缀索...

    dys
  • Oracle参数解析(lock_name_space)

    前面介绍了Oracle的基本参数,从这节开始讲其他的参数,参数从v$parameter中提取

    bsbforever
  • Lucenu和Sphinx介绍

    一、Lucene介绍 1、简介 Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查...

    苦咖啡
  • 【Objective-C】Objective-C语言的动态性

    动态类型指对象指针类型的动态性,具体地说就是使用id类型将对象的类型推迟到运行时才确定,由赋给它的对象类型决定该对象类型(说起来怎么这么绕口),也就是说id修饰...

    iOS_林夕
  • Crosswalk 2015年度盘点

    本文作者:IMWeb niconico 原文出处:IMWeb社区 未经同意,禁止转载 2015 年是 Crosswalk 项目飞速增长的一年,无论在特...

    IMWeb前端团队
  • MySQL通过索引优化-这里可能有你不知道的索引优化细节(二)

    用执行计划分别测试一下union all、in和or,发现union all分两步执行,而in和or只用了一步,效率高一点。

    行百里er
  • Vue这些修饰符帮我节省20%的开发时间

    为了方便大家写代码,vue.js给大家提供了很多方便的修饰符,比如我们经常用到的取消冒泡,阻止默认事件等等~

    前端老道

扫码关注云+社区

领取腾讯云代金券