本文主要是针对python的函数定义做的笔记,详细记录各种需要了解的知识,比如规范、参数、返回值、局部变量、全局变量以及doc_string的相关知识,使用大量简单例子作为解释更容易理解!
1.定义函数
函数通过def关键字定义。def关键字后跟一个函数的 标识符 名称,然后跟一对圆括号(圆括号之中可以包括一些变量名)
,该行以冒号结尾。接下来是一块语句,它们是函数体(因为python的语法,所以在冒号后面接着的函数题需要缩进!!)。下面这个例子将说明这事实上是十分简单的:
def sayHello():
print 'Hello World!' # 缩进的函数体是对函数的具体操作
2.函数形参
参数在函数定义的圆括号对内指定,用逗号分割。当我们调用函数的时候,我们以同样的方式提供值。
注: 函数中的参数名称为 形参 而你提供给函数调用的值称为实参 。说简单点可以认为在定义函数时的参数叫做形参,在正式使用函数时给函数传递的参数叫做实参!
x(a, b): # 在定义函数printMax时传递形参a和b(以逗号分割), a、b用以在定义函数操作的函数体内使用,用以描述函数的使用参数的操作!而在使用时被 实参替代后,真实的操作逻辑会在实参上运行并打印与实参对应的结果! if a > b: # 定义函数体中使用if判断,当然if判断的 缩进也是必需的! print a, 'is maximum' else: print b, 'is maximum'
注:Python 的形参可不只是这么普通!python的参数比较有特色的是可以传递多值!这也与给整个python传递多个参数有类似之处!下面我们来一个一个分析:
2.1 Python 脚本传递参数
此处的脚本指的是你写的.py程序,你知道如果你想运行这个argv.py你只需要使用" python argv.py "即可,那么如果你想给脚本带入参数可以参照下面方法:
# -*- coding: utf-8 -*- # 还记得他是干啥的不? from sys import argv # import语句是将python的功能引入你的脚本中,python不会将所有的功能都给你,而是你指定要什么它才给你什么! script,first,second,third = argv # 本局将几个参数分别赋值给script,first,second,third ,script得到的就是这个脚本!first,second,third 分别得到的是你带入的第一个第二个第三个参数! # 注意下面这四个打印语句,我分别用了不一样的方法,大家参照运行结果观察打印语句的不同! print"The script name is ",script # 本句直接使用print 接一个双引号的字符串再接一个变量 print"The first parameter is %s " % first # 本句使用大家很熟悉的%s参数,注意python的不同是在变量前还需要添加一个%! print"The second parameter is %r " % second # 本句使用的%r参数比较特殊,它一般用于debug,所以它会打印带入的详细信息,而不会优化一些内容!比如打印 \n 他就直接打印'\n'而不会自动转换成换行符! print"The third parameter is "+third # 本句和第一句类似,只不过使用+链接字符串和一个变量!
运行结果是这样的!~
long@zhouyl:~$ vim /tmp/test.py long@zhouyl:~$ python /tmp/test.py you he me The script name is /tmp/test.py The first parameter is you The second parameter is 'he' The third parameter is me
2.2 定义函数时传递参数
这么神奇的带入脚本参数会不会影响函数的形参带入?答案是 Yes! 上面提到的def printMax(a, b): 只是最普通的带参!下面这个会吓尿你:
# -*- coding: utf-8 -*- def print_two(*args): # 关注下这个函数,我带入的是一个以*开头的args参数,其实这个*args与指针比较类似,可以理解为把所有的参数接受后存入一个args的列 表中(列表在后面的博客中会提到) arg1,arg2 = args # 是不是与上面的脚本参数比较类似? print "args1:%r,arg2:%r" % (arg1,arg2) def print_two_again(rg1,arg2): print "args1:%r,arg2:%r" % (arg1,arg2) def print_one(arg1): print "args1:%r" % arg1 def print_none(): print "I got nothing" print_two("Zhou","Zhang") print_two_again("Zhou","Zhang") print_one("Zhang") print_none()
运行起来你可以想象一下:
long@zhouyl:~/python_test/lpthw$ python ex18.py arg1:'Zhou',arg2:'Zhang' arg1:'Zhou',arg2:'Zhang' arg1:'Zhang' I got nothing
2.3.默认参数值
对于一些函数,你可能希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。
def say(message, times = 1): print message * times
注:只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明有默认值的形参而后声明没有默认值的形参。这是因为赋给形参的值是根据位置而赋值的。例如,def func(a, b=5)是有效的,但是def func(a=5, b)是 无效 的。
2.4.关键参数
如果你的某个函数有许多参数,而你只想指定其中的一部分,那么你可以通过命名来为这些参数赋值——这被称作 关键参数 ——我们使用名字(关键字)而不是位置(我们前面所一直使用的方法)来给函数指定实参。
这样做有两个 优势 :
(1) 由于我们不必担心参数的顺序,使用函数变得更加简单了。
(2) 假设其他参数都有默认值,我们可以只给我们想要的那些参数赋值。
def func(a, b=5, c=10): print 'a is', a, 'and b is', b, 'and c is', c func(3, 7) func(25, c=24) func(c=50, a=100)
3.返回值
python的函数返回值与其他语言类似,使用return做返回值的关键字。而且……有了这么奇葩的参数,返回值当然也不甘寂寞了!可以返回多个值哦!
不信?请看示例:
# -*- coding: utf-8 -*- def secret_formula(started): # 定义一个函数,做了简单运算! jelly_beans = started * 500 jars = jelly_beans / 1000 crates = jars / 100 return jelly_beans, jars, crates # 返回多个值! start_point = 10000 beans, jars, crates = secret_formula(start_point) # 使用这种方法接收返回值!是 不是感脚与上面讲的参数比较类似 print "With a starting point of: %d" % start_point print "We'd have %d beans, %d jars, and %d crates." % (beans, jars, crates) # 分 别打印我们接受到的几个返回值 start_point = start_point / 10 print "We can also do that this way:" print "We'd have %d beans, %d jars, and %d crates." % secret_formula(start_point) # 其实~灵活的python可以直接打印返回值的啦!
运行结果可以想象:
$ python ex24.py With a starting point of: 10000 We'd have 5000000 beans, 5000 jars, and 50 crates. We can also do that this way: We'd have 500000 beans, 500 jars, and 5 crates.
4.局部变量
当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的。这称为变量的 作用域 。所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开始。
5.全局变量
如果你想要为一个定义在函数外的变量赋值,那么你就得告诉Python这个变量名不是局部的,而是全局 的。我们使用global语句完成这一功能。没有global语句,是不可能为定义在函数外的变量赋值的。
你可以使用定义在函数外的变量的值(假设在函数内没有同名的变量)。然而,我并不鼓励你这样做,并且你应该尽量避免这样做,因为这使得程序的读者会不清楚这个变量是在哪里定义的。使用global语句可以清楚地表明变量是在外面的块定义的。
6.DocStrings
你可以使用__doc__(注意双下划线)调用定义函数的文档字符串属性(属于函数的名称)。如下例子所示:
# -*- coding: utf-8 -*- def printMax(x, y): '''Prints the maximum of two numbers. The two values must be integers.''' print"x=%s,y=%s" % (x, y) if x > y: print "%s is more bigger than %s" % (x, y) else: print "%s is more bigger than %s" % (y,x) printMax(3, 5) # 正常使用函数 print "This is the doc message about printMax function:\n"+printMax.__doc__ # 打印函数的doc信息
运行结果是这样的!
long@zhouyl:~/python_test/lpthw$ python doc.py x=3,y=5 5 is more bigger than 3 This is the doc message about printMax function: Prints the maximum of two numbers. The two values must be integers.
7.Lambda函数
Python支持一种有趣的语法,它允许你快速定义单行的最小函数,这些叫做lambda的函数,是从Lisp中借用来的,可以用在任何需要函数的地方。
eg.
>>> def f(x): # 普通的函数定义,返回值为参数乘2 ... return x*2 ... >>> f(3) # 普通定义的函数定义,使用函数名加参数,最普通不过 6 >>> g = lambda x:x*2 # 这就是我们所说的lambda函数,说完成的功能与上面的普通函数一样。 # 注意:1、整个函数定义在一行内完成 # 2、参数列表周围没有括号,而且忽略了return关键字(隐含存在,因为整个函数只有一行),提一下:lambda函数可以接收任意多个参数(也可以使用可选参数)并且返回单个表达式的值。 # 3、该行数没有函数名称,但是可以将它赋给一个变量,这个变量就相当于函数名,从下面调用此函数可以看出! >>> g(3) 6 >>> (lambda x:x*2)(3) # 使用lambda函数时可以不赋值给变量(通过变量调用),直接带参使用,这也展示了lambda函数是一个内联函数。 6
Lambda函数是一种代码风格,不一定要使用它们,而且任何能够它们的地方,都可以定义一个单独的普通函数来实现。