局部命名空间为各个参数值创建了一个名字,一旦函数开始执行,就能访问这个名字了。

在函数调用时,有非关键字参数和关键字参数之分,非关键字参数必须位于关键字参数之前。

在函数定义时,严格的顺序是:位置参数,默认参数,可变长元组,可变长字典。

一:调用函数时的参数

a:关键字参数

关键字参数的概念仅仅针对函数的调用。这种理念是让调用者通过函数调用中的参数名字来区分参数。这样规范允许参数不按顺序,因为解释器能通过给出的关键字来匹配参数的值。

假设有一个函数叫做net_conn(),需要两个参数host 和port:

def net_conn(host, port):
net_conn_suite

只要按照函数声明中参数定义的顺序,输入恰当的参数,自然就可以调用这个函数:net_conn('kappa',8080)

host 参数得到字符串'kappa', port 参数得到整数8080。

也可以不按照函数声明中的参数顺序输入,但是要输入相应的参数名,如下例:net_conn(port=8080, host='chino')

b:参数组

Python允许通过一个把元组、列表(非关键字参数)或字典(关键字参数)作为参数组传递给函数。也就是说,可以将所有参数放进一个元组或者字典中,仅仅用这些装有参数的容器来调用一个函数,而不必显式地将它们放在函数调用中:func(*tuple_grp_nonkw_args,  **dict_grp_kw_args)

其中的tuple_grp_nonkw_args是以元组或列表形式体现的非关键字参数组,dict_grp_kw_args 是装有关键字参数的字典。实际上,也可以给出形参!这些参数包括标准的位置参数和关键字参数,所以在python中允许的函数调用的完整语法为:

func(positional_args,  keyword_args,  *tuple_grp_nonkw_args,  **dict_grp_kw_args)

比如:

def fun(a, b, c, d, e, f, g):
print 'a is', a
print 'b is', b
print 'c is', c
print 'd is', d
print 'e is', e
print 'f is', f
print 'g is', g alist = [1,3,4]
adict = {'d':5, 'e':6, 'f':7, 'g':8}

fun(*alist, **adict)结果是:

a is 1
b is 3
c is 4
d is 5
e is 6
f is 7
g is 8

二:声明函数时的参数

a:位置参数

位置参数就是我们熟悉的标准化参数。位置参数必须以在被调用函数中定义的准确顺序来传递。比如:

def foo(who):
print ‘Hello,’, who

这里foo函数就有一个位置参数。所以,调用foo时,必须有唯一的一个参数,不能多也不能少。

无论何时调用函数,都必须提供函数的所有位置参数。可以不按顺序地将关键字参数传入函数。所以,上例可以这样调用:

foo('world')
foo(who = 'hehe')

b:默认参数

默认参数就是声明了默认值的参数。因为给参数赋予了默认值,所以, 在函数调用时,可以不向该参数传入值。

注意:在函数定义时,所有的位置参数必须出现在任何一个默认参数之前。否则的话,解释器将不知道如何匹配参数。例子如下:

def net_conn(host, port=80, stype='tcp'):
print 'host is ', host
print 'port is ', port
print 'stype is ', stype net_conn('phaze', 8080, 'udp')
net_conn('kappa')
net_conn('chino', stype='icmp') net_conn(stype='udp', host='solo')
net_conn('deli', 8080)
net_conn(port=81, host='chino')

注意:在函数调用时,非关键字参数必须在关键字参数之前,所以,如果最后一个例子为:net_conn(port=81,'chino')的话,就会报语法错误:SyntaxError: non-keyword arg after keyword arg

在Python中,函数还可以处理可变数量的参数。变长的参数,称之为非正式参数。它们在函数声明中不是显式命名的,因为参数的数目在运行时之前是未知的。

Python 有两种支持变长参数的方法,在函数调用中,可以使用*和**符号来指定元组和字典的元素作为非关键字以及关键字参数。在函数定义中,将再次使用相同的符号,表示可变参数。

c:非关键字可变长参数

当函数被调用的时候,所有的位置参数和默认参数被赋值之后,剩下的非关键字参数就会按顺序插入到一个元组中。

这种机制类似于C语言中的“varargs“语法。在Python中迭代所有的元组元素和在C中用va_arg 是相同的。

可变长的参数元组必须在位置和默认参数之后,带元组(或者非关键字可变长参数)的函数普遍的语法如下:

def function_name([formal_args,] *vargs_tuple):
"function_documentation_string"
function_body_suite

星号操作符之后的形参将作为元组传递给函数,元组保存了所有传递给函数的"额外"的参数(匹配了所有位置和具名参数后剩余的)。如果没有给出额外的参数,元组为空。

如果没有可变参数,则只要在函数调用时给出不正确的函数参数数目,就会产生一个TypeError异常。通过末尾增加一个可变的参数列表变量,我们就能处理当超出数目的参数被传入函数的情形,因为所有的额外(非关键字)参数会被添加到变量参数元组。

例子如下:

def tupleVarArgs(arg1, arg2='defaultB', *theRest):
print 'formal arg1:', arg1
print 'formal arg2:', arg2
for eachXtrArg in theRest:
print 'another arg:', eachXtrArg >>>tupleVarArgs('abc')
formal arg 1: abc
formal arg 2: defaultB
>>>
>>>tupleVarArgs(23, 4.56)
formal arg 1: 23
formal arg 2: 4.56
>>>
>>>tupleVarArgs('abc', 123, 'xyz',456.789)
formal arg 1: abc
formal arg 2: 123
another arg: xyz
another arg: 456.789

d:关键字可变长参数

如果有不定数目的或者额外的关键字参数,则剩余的关键字参数被放入一个字典中,字典中键为参数名,值为相应的参数值。

使用字典作为可变长关键字参数来应对额外关键字参数的函数定义的语法如下:

def function_name([formal_args,] [*vargst,] **vargsd):
function_documentation_string
function_body_suite

例子:

def dictVarArgs(arg1, arg2='defaultB', **theRest):
print 'formal arg1:', arg1
print 'formal arg2:', arg2
for eachXtrArg in theRest.keys():
print 'Xtra arg %s: %s' % (eachXtrArg, str(theRest[eachXtrArg])) >>>dictVarArgs(1220, 740.0, c='grail')
formal arg1: 1220
formal arg2: 740.0
Xtra arg c: grail
>>>
>>>dictVarArgs(arg2='tales', c=123, d='poe', arg1='mystery')
formal arg1: mystery
formal arg2: tales
Xtra arg c: 123
Xtra arg d: poe
>>>
>>>dictVarArgs('one', d=10, e='zoo', men=('freud', 'gaudi'))
formal arg1: one
formal arg2: defaultB
Xtra arg men: ('freud', 'gaudi')
Xtra arg d: 10
Xtra arg e: zoo

下面是更多调用带有可变长参数的例子,注意,在调用时,如果混用关键字参数和非关键字参数,则先匹配位置参数,关键字参数只能处理位置参数之后的参数。比如:

def fun(a, b, c):   pass
fun(100, c = 1, a = 2) 

会发生语法错误:TypeError: fun() got multiple values for keyword argument 'a'

def newfoo(arg1, arg2, *nkw, **kw):
print 'arg1 is:', arg1
print 'arg2 is:', arg2
for eachNKW in nkw:
print 'additional non-keyword arg:', eachNKW
for eachKW in kw.keys():
print "additional keyword arg '%s': %s" %(eachKW, kw[eachKW]) >>>newfoo('wolf', 3, 'projects', freud=90, gamble=96)
arg1 is: wolf
arg2 is: 3
additional non-keyword arg: projects
additional keyword arg 'freud': 90
additional keyword arg 'gamble': 96 >>>newfoo(10, 20, 30, 40, foo=50, bar=60)
arg1 is: 10
arg2 is: 20
additional non-keyword arg: 30
additional non-keyword arg: 40
additional keyword arg 'foo': 50
additional keyword arg 'bar': 60

下面,将非关键字参数放在元组中,将关键字参数放在字典中:

>>>newfoo(2, 4, *(6, 8), **{'foo': 10, 'bar': 12})
arg1 is: 2
arg2 is: 4
additional non-keyword arg: 6
additional non-keyword arg: 8
additional keyword arg 'foo': 10
additional keyword arg 'bar': 12 >>>aTuple = (6, 7, 8)
>>>aDict = {'z': 9}
>>>newfoo(1, 2, 3, x=4, y=5, *aTuple, **aDict)
arg1 is: 1
arg2 is: 2
additional non-keyword arg: 3
additional non-keyword arg: 6
additional non-keyword arg: 7
additional non-keyword arg: 8
additional keyword arg 'y': 5
additional keyword arg 'x': 4
additional keyword arg 'z': 9 

注意我们的元组和字典参数仅仅是被调函数中最终接收的元组和字典的子集。额外的非关键字值‘3’以及关键字‘x’和‘y'对也被包含在最终的参数列表中。

Python基础:10函数参数的更多相关文章

  1. python基础之函数参数,名称空间,以及函数嵌套

    函数进阶内容梗概: 1. 函数参数--动态传参 2. 名称空间, 局部名称空间, 全局名称空间, 作⽤用域, 加载顺序. 3. 函数的嵌套 4. gloabal , nonlocal 关键字 1. 函 ...

  2. python基础之函数参数、嵌套、返回值、对象、命名空间和作用域

    函数的使用原则 函数的使用必须遵循:先定义后使用的原则 函数的定义,与变量的定义是相似的,如果没有事先定义函数而直接引用就相当于在引用一个不存在变量名 定义阶段:只检测语法,不执行代码,当出现语法错误 ...

  3. Python基础之函数参数与返回值进阶

    参数作用:如果外界希望在函数内部处理数据,就可以将数据作为参数传入函数内部: 返回值作用:如果希望一个函数函数执行完成后,向外界报告函数的执行结果,就可以使用函数的返回值. 函数的返回值 进阶 利用元 ...

  4. python基础-4 函数参数引用、lambda 匿名函数、内置函数、处理文件

    上节课总结 1.三元运算 name=“name1”if 条件 else “name2” 2.深浅拷贝 数字.字符串 深浅,都一样 2.其他 浅拷贝:只拷贝第一层 深拷贝:不拷贝最后一层 3.set集合 ...

  5. Python基础之函数参数

    一.实参 1.实参分类: 2.实参基础代码: def fun01(a, b, c): print(a) print(b) print(c) # 位置传参:实参与形参的位置依次对应 fun01(1, 2 ...

  6. python基础知识06-函数基础和函数参数

    函数基础和函数参数 可迭代对象:序列类型 range . 1.函数的定义 def 函数名(参数): pass return 表达式 ,不能是赋值语句.不写默认返回None.用逗号隔开返回一个元组. 函 ...

  7. python基础——filter函数

    python基础——filter函数 Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函 ...

  8. 八. Python基础(8)--函数

    八. Python基础(8)--函数 1 ● 函数返回布尔值 注意, 自定义的函数也可以是用来作逻辑判断的, 例如内置的startswith()等函数. def check_len(x):     ' ...

  9. 『Python基础-10』字典

    # 『Python基础-10』字典 目录: 1.字典基本概念 2.字典键(key)的特性 3.字典的创建 4-7.字典的增删改查 8.遍历字典 1. 字典的基本概念 字典一种key - value 的 ...

  10. python基础——匿名函数

    python基础——匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便.  在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时 ...

随机推荐

  1. JS 生成二维码和加上logo图片

    参考链接:https://www.cnblogs.com/chiyi/p/5710324.html,http://www.jq22.com/jquery-info294 demo链接:demo查看 d ...

  2. Java Servlet实现下载文件

    一.配置servlet 在WebContent(以前的eclipse版本是WebRoot)文件夹下,有一个web.xml 修改web.xml ,加入以下代码 <servlet> <s ...

  3. cmd下带参数执行python文件

    在一个文件下下创建程序代码,     sys.argv 即后续cmd中需要传入的参数列表,     sys.argv[0]即要执行的文件名     sys.argv[n]即参数的字符串 # -*- c ...

  4. webpack4进阶配置

    移动端CSS px自动转换成rem 需要两步来实现: px2rem-loader 在构建阶段将px转换成rem lib-flexible 页面渲染时动态计算根元素的font-size值(手机淘宝开源库 ...

  5. 再问你Java内存模型的时候别再给我讲堆栈方法区

    在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事情.要说计算机的内存模型,就要说一下一段古老的历史,看一下为什么要有内存模型 ...

  6. 数据库安全 (ch.4)

    4.2.4 授权与回收 使用 Grant 授予权限 使用Revoke 回收权限 Grant [权限] ON *.. to * [with grant option] with grant option ...

  7. ucore os 前初始化

    BIOS 初始化完成说起 连接的时候指定了 -Ttext 0x7c00 也指定了 -e start 所以booasm.S 中的start 就呗钦定为程序入口了. 开始就是 屏蔽中断 初始化段寄存器 使 ...

  8. 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】

    [题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...

  9. Leetcode661.Image Smoother图片平滑器

    包含整数的二维矩阵 M 表示一个图片的灰度.你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽可能多 ...

  10. ssdb常用知识点

    ssdb备份与恢复 http://ssdb.io/docs/zh_cn/backup.html ssdb注意事项 建议将logger.level设置为 debug 级别. 配置文件 deny,allo ...