Python入门教程-04 再论函数
2014-04-13 17:37
435 查看
1. Overview
在上一节中,我们简单用到了函数、简单介绍了函数的语法。本节进一步介绍和函数相关的一些方面。2. 函数:返回值
在C、C++、Java中,只有函数function这一种说法;如果大家用过VB等编程语言,知道会有函数function和过程process之分,前者有返回值,后者没有返回值。那么在Python中,和C/C++/Java一样,只有function一说。继续前面Fibonacci的例子,但这里做一定的修改:
#!/usr/bin/env python def Fibonacci(n): if n == 0: return 0 elif n == 1: return 1 else: return Fibonacci(n - 1) + Fibonacci(n - 2) def Dump_Fibonacci(n, val): print "Fibonacci(%d) = %d\n" % (n, val) n = 10 val = Fibonacci(n) Dump_Fibonacci(n, val)
这里,我们定义了2个函数:Fibonacci和Dump_Fibonacci。前者返回一个整数,后者不返回任何数据。
3. return语句
return语句的使用方法和其他编程语言是一样的,其实无需多言。这里只简单指出:在Python中,return语句之后,仍然可以有其他的语句。什么意思呢?用过Java语言的知道,不能存在不可达(Unreachable)代码。比如在return语句之后,再定义根本无法执行到的一些代码,那么就会有编译错误。而在Python中,使用和C/C++一样的语法规则,即在return语句之后还可以有其他的代码。这样的语法的好处就是,便于调试。——因为有时候一个函数的功能很复杂、代码很长,那么就可以在函数中间添加return来调试部分代码,从而加快调试的效率。——BTW:如果经常出现这种情况,就要考虑该函数是否需要重构!
示例:
flying-bird@flyingbird:~/examples/python$ cat unreachable.py #!/usr/bin/env python def Unreachable(): print "first line." return print "Unreachable code." Unreachable() flying-bird@flyingbird:~/examples/python$ ./unreachable.py first line. flying-bird@flyingbird:~/examples/python$
4. 再论返回值
在前面介绍了函数的常用规则之后,我们简单提及一个事实,即:虽然函数没有return语句,但该函数仍然有返回值,只是该返回值极其特殊,为None。因为是None,自然没有多大用处。示例:
flying-bird@flyingbird:~/examples/python$ cat return_none.py #!/usr/bin/env python def Print(msg): print msg def Add(x, y): z = x + y ret = Print("Hello, python!") print "ret: ", ret ret = Add(3, 2) print "ret: ", ret flying-bird@flyingbird:~/examples/python$ ./return_none.py Hello, python! ret: None ret: None flying-bird@flyingbird:~/examples/python$
注意,这里给出Add()是有意的。因为在某些语言中,如果没有return语句,那么它会将函数最后执行的一条语句的结果作为返回值。而上面的示例说明了,在Add()函数中,虽然最后一条语句计算除了z,但并没有将z作为返回值。
5. 参数的数据类型
前面已多次提及Python中的变量不需要定义其数据类型(无语法支持),那么如何才能知道函数参数是什么类型呢?答案很简单:基于契约,即caller和callee之间的调用约定。当然,可以在函数中对入参的类型进行校验,如使用
Python入门教程-02 变量 一文提到的type()方法。但实际项目中,很少采用这种做法,因为这已经涉嫌“过设计”了。
进一步地,如果caller提供的参数非法,那么脚本执行时,会直接异常终止。示例:
flying-bird@flyingbird:~/examples/python$ cat return_none.py #!/usr/bin/env python def Print(msg): print msg def Add(x, y): z = x + y ret = Print("Hello, python!") print "ret: ", ret ret = Add(3, "2") print "ret: ", ret flying-bird@flyingbird:~/examples/python$ ./return_none.py Hello, python! ret: None Traceback (most recent call last): File "./return_none.py", line 12, in <module> ret = Add(3, "2") File "./return_none.py", line 7, in Add z = x + y TypeError: unsupported operand type(s) for +: 'int' and 'str' flying-bird@flyingbird:~/examples/python$
6. Pass-by-Val or Pass-by-Ref
继续和C/C++进行类比。在C/C++中,存在传值和传引用的概念。那么在Python是否也是如此呢?或者说,传给函数的变量,可以修改吗?为此,先通过例子进行说明:
flying-bird@flyingbird:~/examples/python$ cat incr.py #!/usr/bin/env python def Inc(x): x = x + 1 return x x = 100 y = Inc(x) print "x: ", x print "y: ", y flying-bird@flyingbird:~/examples/python$ ./incr.py x: 100 y: 101 flying-bird@flyingbird:~/examples/python$
通过这个小例子,我们似乎可以给出如下结论:
Python中函数参数不存在传值或传引用的说法,或者说,全部都是传值的形式;
在函数内部可以修改入参的值,但该修改仅仅在该函数内部其作用,并不会影响调用程序中该变量的值;
但事实是否果真如此呢?如果大家有Java语言编程经验的话,或许还知道值对象和引用对象的概念。在深入介绍该专题之前,我们再给出一个例子:
flying-bird@flyingbird:~/examples/python$ cat incr.py #!/usr/bin/env python def Inc(x): x = x + 1 return x def Append(x): x.append(100) return x x = 100 y = Inc(x) print "x: ", x print "y: ", y x = [1, 2, 3] y = Append(x) print "x: ", x print "y: ", y flying-bird@flyingbird:~/examples/python$ ./incr.py x: 100 y: 101 x: [1, 2, 3, 100] y: [1, 2, 3, 100] flying-bird@flyingbird:~/examples/python$
这个例子用到了Python中非常重要的一种数据类型,即list。至此,说明了Python的入参存在和java类似的处理机制,而和C++又存在差异了。——如果是值引用,后者会使用拷贝构造定义出一个临时变量。
我们先了解Python函数入参的这个复杂性,在后续介绍list, set, dictionary, class等专题的时候,我们会再次进行这方面的讲解。
7. 缺省参数
和C++一样,Python也支持缺省参数。即在定义函数的时候,可以为这个参数定义一个缺省值。如此在调用该函数的时候,如果没有指定该参数,则使用该参数的缺省值;如果指定了具体的值,则使用传入的这个数据。示例:flying-bird@flyingbird:~/examples/python$ cat default_arg_value.py #!/usr/bin/env python def Inc(x, step=1): x = x + step return x def debug(step): x = 100 if step == 1: y = Inc(x) else: y = Inc(x, step) print "x: ", x print "y: ", y debug(1) debug(10) flying-bird@flyingbird:~/examples/python$ ./default_arg_value.py x: 100 y: 101 x: 100 y: 110 flying-bird@flyingbird:~/examples/python$
8. 其它
关于函数还有很多专题可以介绍,比如命名参数、变长参数等等。但在目前,我们先掌握前面介绍的基础知识。待所有基本语法全部浏览一遍之后,我们再回过头来深入每一个专题。——可以将我们的学习过程看作是敏捷迭代的方式,即通过快速地掌握最基本的语法,能够编写基本的、小型的、常见的Python程序。然后逐步深入每一个专题,逐步完善我们的Python知识。相关文章推荐
- python BeautifulSoup模块的安装
- Python Sleep休眠函数
- python中的BeautifulSoup模块
- python的Mysql和MySQLdb的安装
- 关于python多线程编程中join()和setDaemon()的一点儿探究
- python抓取并保存html页面的乱码解决办法
- Python3.4字符串包含 & 集合
- sorted(),list.sort()函数应用排序字符串的ip地址
- python标准库和扩展库
- Python在Windows平台应用
- 将 XML 和 Python结合起来
- Python入门教程-03 缩进、if-else,及函数定义
- Python3.4字符串对齐/删除空格/合并/反转
- 【python学习笔记】-【0】
- python模拟浏览器webdriver登陆网站后抓取页面并输出
- python魔法方法
- 【转】Python中string的strip,lstrip,rstrip用法
- Python3.4每次处理一个字符
- python操作mysql数据库
- python操作mysql数据库