python学习[第十七篇] 函数一
python学习[第十七篇] 函数一
函数概念
函数就是对程序逻辑进行结构化或者过程化的一种编程方法
返回值与函数类型
函数没有返回值时,返回的是None。
函数有一个返回值时,返回的是object本身。
函数有多个返回值是,返回的是元组对象。
函数调用
关键字参数
关键字参数仅仅针对函数的调用,让调用者通过函数调用中的参数名字来区分参数。
>>> def test(x,y): ... print x,y ... >>> test(x=45,y=34) 45 34
默认参数
默认参数就是声明了默认值的参数,如果存在非默认参数,那么非默认参数必须在默认参数左(前)边。调用函数时,可以不对默认参数进行赋参,但必须加入非默认参数
#如果存在非默认参数,那么非默认参数必须在默认参数左(前)边 >>> def foo(x=45,y): ... print x ... print y ... File "<stdin>", line 1 SyntaxError: non-default argument follows default argument >>> def foo(x,y=45): ... print x,y ... >>> foo(10) 10 45 >>> foo(15,20) 15 20 >>> foo(x=15,y=20) 15 20 >>> foo(y=15,x=20) 20 15
参数组
python允许程序执行一个没有显示定义参数的哦函数,相应的方法是通过一个元组(非关键字参数),或字典(关键字参数)作为参数组传递给函数。
func(*tuple_grp_nonkw_args ,**dict_grp_kw_args)
其中的tuple是以元组形式提示的非关键字参数组,dict是装有关键字参数的字典。
创建函数
def 语句
python中通过def来创建函数
def function_name(arguments): "function_documentation_string" function_body_suite
前向引用
python中不允许在函数未声明之前调用该函数。
#未定义bar函数 def foo(): print "bar before definite bar" bar() foo() #在foo函数前定义bar函数。 def bar(): print 'bar' def foo(): print "bar before definite bar" bar() foo() #在foo函数后定义bar函数,但是在定义bar函数后,调用foo函数 def foo(): print "bar before definite bar" bar() def bar(): print 'bar' foo()
函数的属性
函数可以有__doc__ version等属性
>>> def foo(): ... 'this is func foo' ... print 'foo' ... >>> print foo.__doc__ this is func foo >>> foo.version=0.1 >>> print foo.version 0.1
内嵌函数
函数中可以创建另一个函数,但是内嵌函数作用域即生命周期只在外部函数内。所有在全局局面无法调用内嵌函数
>>> def foo(): ... def bar(): ... print 'bar called' ... print 'foo called' ... bar() ... >>> foo <function foo at 0x0260F8F0> >>> foo() foo called bar called >>> bar() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'bar' is not defined
函数传递
函数名可以赋值给其他引用,就像变量赋值一样。就是说可以用其他变量来当做函数的别名。
>>> def foo(): ... print 'foo' ... >>> xxx=foo >>> xxx() foo
形式参数
python的形参集合由在调用时要传入函数的所有参数组成。这些参数与函数声明中的参数列表精确地配对。包括了必要参数(即以正确的定位顺序来传入的参数),关键字参数(以顺序或者不按顺序传入,但是带有参数列表中定义过的关键字)和所有默认参数值,函数调用时不必要指定的参数。
声明函数时创建的局部命名空间为各个参数值,创建了一个名字,一但函数开始执行就能访问这个名字。
位置参数
位置参数必须以在被调用函数中定义的准确顺序来传递。如果没有任何默认参数的话,传入函数的参数的精确的数目必须和声明的数字一致。
>>> def foo(arg1,arg2): ... print 'this is ',arg1 ... print 'this is ',arg2 ... >>> #两个参数都是未知参数,所以传入数目必须与定义的参数数目一致 >>> foo(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: foo() takes exactly 2 arguments (1 given) >>> foo('arg1','arg2') this is arg1 this is arg2 >>> foo(('arg1',),'arg2') this is ('arg1',) this is arg2 #传入的位置参数按顺序来传递 >>> foo('arg2','arg1') this is arg2 this is arg1
默认参数
对于默认参数如果在函数调用时,没有给参数提供值,则使用预先定义的默认值。默认值在函数定义的标题行给出。语法:参数名=默认值。
python中,使用默认值声明变量的语法是所有的位置参数必须出啊先在任何一个默认参数之前。调用时也如此
#标准语法如下 def func(posargs,defarg1=val1,defarg2=var2,....): 'function_document_string' function_body_suite
#默认参数必须在位置参数后面定义 >>> def func(t1='1',pos_arg1,pos_arg2,test='111',var2='222'): ... print t1,pos_arg1,pos_arg2,test,var2 ... File "<stdin>", line 1 SyntaxError: non-default argument follows default argument >>> def func(pos_arg1,pos_arg2,test='111',var2='222'): ... print pos_arg1,pos_arg2,test,var2 ... #默认参数可以无需赋值 >>> func(1,2) 1 2 111 222 #可以对默认参数进行赋值 >>> func(1,2,3,4) 1 2 3 4 #调用时,默认参数必须在位置参数后面赋值 >>> func(test='222',1,2) File "<stdin>", line 1 SyntaxError: non-keyword arg after keyword arg >>> func(test=(1,2,3,4) ... KeyboardInterrupt
可变长度的参数
可变长度的参数在函数声明中不是显示命名的,因为参数的数目在运行之前是未知的。由于函数调用提供了关键字以及非关键字两种参数类型,python用两种方法来支持变长参数。
python中使用*和 **符号来指定元组和字典的元素作为非关键字(元组)以及关键字参数(字典)的方法。
非关键字可变长参数(元组)
当函数被调用的时候,所有的形参(必须的和默认的)都将值付给了在函数声明中相对应的局部变量。剩下的非关键字参数按顺序插入到一个元组中便于访问。
语法如下:
*号之前的形参键作为元组传递个函数,元组保存了所有传递给函数的额外的参数。如果没有给出额外的参数元组为空。额外的非关键字参数会被添加到变量参数元组,由于和位置参数必须放在关键字参数之前一样的原因,所有的形式参数必须先于非正式的参数之前出现。
#可变长的参数元组语法 def function_name([formal_args,]*vargs_tuple): 'function_documentation_string' function_body_suite
实例如下
#可变长度实例 >>> def func(test1,*args): ... print 'position arg:' ,test1 ... for var_arg in args: ... print 'var long args', var_arg ... >>> #只赋值位置参数 >>> func('test1') position arg: test1 #赋值位置参数和可变参数 >>> func('test1','test2','test3') position arg: test1 var long args test2 var long args test3
关键字可变长参数(字典)
在我们有补丁数目的或者额外集合的关键字的情况中,参数被放入一个字典中,字典中键为参数名,值为相应的参数值。
为了区分关键字参数和非关键字参数,使用了双星号(**),关键字变量参数应该为函数定义的最后一个参数,带**.
def function_name([formal_rags,] [*vargst,] **vargsd): 'function_documentation_string' function_body_suite
实例1
>>> def func(test1,test2='test2',**args): ... print 'formal arg1 ',test1 ... print 'formal arg2 ',test2 ... for xarg in args: ... print 'xarg is ',xarg ... #位置参数赋值,默认参数赋值,没有可变参数赋值 >>> func('test1','test2') formal arg1 test1 formal arg2 test2 #位置参数已赋值,默认参数未赋值,可变参数有1个 >>> func('test1',test3='test3') formal arg1 test1 formal arg2 test2 xarg is test3 #位置参数已赋值,默认参数已赋值,可变参数有1个 >>> func('test1',test2='test2',test3='test3') formal arg1 test1 formal arg2 test2 xarg is test3 #位置参数已赋值,默认参数已赋值,可变参数有2个 >>> func('test1',test2='test2',test3='test3',test4='test4') formal arg1 test1 formal arg2 test2 xarg is test3 xarg is test4
实例2 非关键字可变参数,和关键字可变参数同时存在
>>> def func(test1,test2='test2',*args,**vargs): ... print 'formal arg1 ',test1 ... print 'formal arg2 ',test2 ... for x in args: ... print 'non-keyword arg ',x ... for y in vargs.keys(): ... print 'keyword arg ', vargs[y] ... >>> func('var1','var2','var3',test4='var4') formal arg1 var1 formal arg2 var2 non-keyword arg var3 keyword arg var4
调用带有可变长参数对象函数
#定义 >>> def func(test1,test2='test2',*args,**vargs): ... print '#### formal arg ####' ... print 'formal arg1 ',test1 ... print 'formal arg2 ',test2 ... print '#### non keyword var ####' ... for x in args: ... print 'non-keyword arg ',x ... print '#### keyword var ####' ... for y in vargs.keys(): ... print 'keyword arg ',y ... print 'keyword arg var', vargs[y] ... #调用时,将元组作为 非关键字可变参数 ,将字典作为 关键字可变参数 #例如 (1,2)元组作为非关键字可变参数, # {'foo':10,'var':12} 字典作为关键字可变参数, func('var1','var2',*(1,2),**{'foo':10,'var':12}) >>> func('var1','var2',*(1,2),**{'foo':10,'var':12}) #### formal arg #### formal arg1 var1 formal arg2 var2 #### non keyword var #### non-keyword arg 1 non-keyword arg 2 #### keyword var #### keyword arg var keyword arg var 12 keyword arg foo keyword arg var 10
###函数一end