【Python基础学习篇八】Python函数

函数是一段可以重复多次调用的代码,通过输入的参数值,返回需要的结果。

一、函数的定义

函数的定义使用保留字def定义。函数在使用前必须定义,函数的类型即返回值的类型。

Python函数定义的格式如下:

def 函数名 (参数1[=默认值1],参数2[=默认值2]...):
    ...
return 表达式

函数名可以是字母、数字或下划线组成的字符串,但不能以数字开头。函数的参数放在一对圆括号中,参数的个数可以有一个或多个,参数之间用逗号隔开,这种参数称之为形式参数。

例子:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
#函数的定义
from __future__ import division
def arithmetic(x,y,operator):
    result = {
        "+":x + y,
        "-":x - y,
        "*":x * y,
        "/":x / y
    }

arithmetic()已经创建成功,剩下的就是函数的调用的问题了。函数可以在当前文件中调用,也可以在其他模块中调用。

函数调用的格式如下所示:

函数名(实参1,实参2...)

函数的调用采用函数名加一对圆括号的方式,圆括号内的参数是传递给函数的具体值。函数调用中的实参列表分别与函数定义中的形参列表对应。

下图说明了实际参数和形式参数的对应关系。

arichmetic()的调用如下所示:

#函数的调用
print arithmetic(1,2,"+")

注意:

实际参数必须与形式参数一一对应,参数的顺序和参数的类型必须一致,否则将出现错误计算。如果参数提供默认值,顺序可以不一致。

二、函数的参数

在Python中的任何变量都是对象,所以参数只支持引用传递的方式。Python通过名字绑定的机制,把实际参数的值和形式参数的名称绑定在一起。即把形式参数传递到函数所在的局部命名空间中,形式参数和实际参数指向内存中的同一个存储空间。

函数的参数支持默认值。当某个参数没有传递实际的值时,函数将使用默认参数计算。

例如可以给arichmetic()参数都提供一个默认值。

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def arithmetic(x = 1,y = 1,operator = "+"):
    result = {
        "+":x + y,
        "-":x - y,
        "*":x * y,
        "/":x / y
    }
    return result.get(operator)

print arithmetic(1,2)
print arithmetic(1,2,"=")
print arithmetic(y=3,operator = "-")
print arithmetic(x=4,operator = "-")
print arithmetic(y=3,x=4,operator = "-")

输出结果:

---------- python2.7 ----------
3
None
-2
3
1

输出完成 (耗时 0 秒) - 正常终止

参数可以是变量,也可以是元组、列表等内置数据结构:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def arithmetic(args = [],operator = "+"):
    x = args[0]
    y = args[1]
    result = {
        "+":x + y,
        "-":x - y,
        "*":x * y,
        "/":x / y
    }

print arithmetic([1,2])

输出结果:

---------- python2.7 ----------
None

输出完成 (耗时 0 秒) - 正常终止

由于参数实现了名字绑定的机制,所以在使用默认参数时,可能会出现预期之外的结果:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def append(args = []):
    args.append(0)
    print args

append()
append([1])
append()

输出结果:

---------- python2.7 ----------
[0]
[1,0]
[0,0]

输出完成 (耗时 0 秒) - 正常终止

为了避免这个问题,可以在append()中添加一个条件判断语句。如果列表中args中没有任何元素,则先把args列表置空,谈后再添加元素:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def append(args = []):
    if len(args) <=0:
        args = []
    args.append(0)
    print args

append()
append([1])
append()

输出结果:

---------- python2.7 ----------
[0]
[1, 0]
[0]

输出完成 (耗时 0 秒) - 正常终止

在程序的开发过程中,常常需要传递可变长度的参数。在函数的参数前使用标识符“*”可以实现这个要求。“*”可以引用元组,把多个参数组合到一个元组中。

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func(* args):
    print args
func(1,2,3)

输出结果:

---------- python2.7 ----------
(1, 2, 3)

输出完成 (耗时 0 秒) - 正常终止

三、函数的返回值

函数的返回值使用return语句,return后面可以是变量或表达式。

例子:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
from __future__ import division
def arithmetic(x,y,operator):
    result = {
        "+":x + y,
        "-":x - y,
        "*":x * y,
        "/":x / y
    }
    return result.get(operator)

Python中即使函数没有返回值,依然可以获得返回值。

例子:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func():
    pass

print func()

输出结果:

---------- python2.7 ----------
None

输出完成 (耗时 0 秒) - 正常终止

None是Python中的一个对象,不属于数字也不属于字符串。当函数中的return语句不带任何参数时,返回的结果也是None

例子:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func():
    return

print func()

输出结果:

---------- python2.7 ----------
None

输出完成 (耗时 0 秒) - 正常终止

如果需要返回多个值,可以把这些值打包到元组中。在调用时,对返回的原则解包即可。

例子:输入0、1、2,返回2、1、0

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func(x,y,z):
    l = [x,y,z]
    l.reverse()
    numbers = tuple[1]
    return numbers

x,y,z = func(0,1,2)
print x,y,z

第二种解决方法:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func(x,y,z):
    l = [x,y,z]
    l.reverse()
    a,b,c = tuple[1]
    return a,b,c

x,y,z = func(0,1,2)
print x,y,z

在一个函数中也可以使用多个return语句。

例如if…else语句的各个分支最后那个,返回不同的结果:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func(x):
    if x > 0:
        return "x > 0"
    elif x == 0:
        return "x = 0"
    else:
        return "x < 0"
print func(-2)

输出结果:

---------- python2.7 ----------
x < 0

输出完成 (耗时 0 秒) - 正常终止

注意:

不推荐在一个函数中使用富哦个return语句,return语句过多往往会造成程序的复杂,这时就需要对代码进行重构了。

如果函数中有多个return语句,可以通过增加一个变量的方法来减少return语句:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func(x):
    if x > 0:
        result = "x > 0"
    elif x == 0:
        result = "x = 0"
    else:
        result = "x < 0"
    return result
print func(-2)

输出结果:

---------- python2.7 ----------
x < 0

输出完成 (耗时 0 秒) - 正常终止

四、函数的嵌套

函数的嵌套是指在函数的内部调用其他函数。Python不仅支持函数体内的嵌套,还支持函数定义的嵌套。

例如:

计算表达式(x+y)*(m-n)的值。

可以把计算步骤分为3步:先计算表达式x+y,其次计算表达式m-n,最后计算两个结果的乘积。

因此,可以设计3个函数。

第一个函数sum()计算x+y的值;

第二个函数sub()计算m-n的值;

第三个函数计算前面两者的乘积。

例子:函数之间的调用操作

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def sum(a,b):
    return a + b
def sub(a,b):
    return a - b
def func():
    x = 1
    y = 2
    m = 3
    n = 4
    return sum(x,y)*sub(m,n)
print func()

输出结果:

---------- python2.7 ----------
-3

输出完成 (耗时 0 秒) - 正常终止

注意:

函数嵌套的层数不宜过多,否则容易造成代码的可读性差、不易维护等问题。一般函数的嵌套调用控制在3层以内为好。

上面的代码可以换一种形式实现,即把函数sum()、sub()放到func()的内部,如下图所示:

例子:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func():
    x = 1
    y = 2
    m = 3
    n = 4
    def sum(a,b):
        return a + b
    def sub(a,b):
        return a - b
    return sum(x,y)*sub(m,n)

print func()

输出结果:

---------- python2.7 ----------
-3

输出完成 (耗时 0 秒) - 正常终止

内部函数sum()、sub()也可以直接使用外部函数func()定义的变量,如下图:

例子:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
def func():
    x = 1
    y = 2
    m = 3
    n = 4
    def sum():
        return x + y
    def sub():
        return m - n
    return sum()*sub()

print func()

输出结果:

---------- python2.7 ----------
-3

输出完成 (耗时 0 秒) - 正常终止

说明:

尽量不要在函数内部定义函数。这种方式不便于程序的维护,容易造成逻辑上的混乱。

五、递归函数

递归函数可以在函数主题内直接或者间接地调用自己,即函数的嵌套是函数本身。递归四一种程序设计方法,使用递归可以减少重复的代码,使得程序变得简洁。

递归的过程分为两个阶段:递推和回归。

递归函数的原理如下:

第一阶段,递归函数在内部调用自己。每一次函数调用又重新开始执行此函数的代码,直到某一级递归程序结束。

第二阶段,递归函数从后往前返回。递归函数从最后一级开始返回,直到返回到第一次调用的函数体内。即递归逐级调用完毕后,再按照相反的顺序逐级返回。

特别说明:

递归函数需要编写递归结束的条件,否则递归程序将无法结束。一般通过判断语句来结束程序。

计算阶乘是一个经典的递归实现。

例如,计算5!的结果。在设计程序时,可以根据n是否等于1进行判断。每次递归调用,传入参数n-1.直到n=1时,返回1!等于1.再依次返回2!、3!、4!、5!的计算结果。如下图所示:

例子:用递归函数实现阶乘的计算过程

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
#计算阶乘
def refunc(n):
    i = 1
    if n > 1:
        i = n
        n = n * refunc(n - 1)
    print "%d! =" %i,n
    return n

refunc(5)

输出结果:

---------- python2.7 ----------
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120

输出完成 (耗时 0 秒) - 正常终止

特别注意:

每次调用递归函数都会复制函数中所有的变量,再执行递归函数。程序需要较多的存储空间,这对程序的性能会有一定的影响。因此,对于没有必要进行递归的程序,最好用其他的方法进行改进。

可以使用reduce()快速实现阶乘的运算:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
#计算reduce阶乘
print "5! =",reduce(lambda x,y:x * y,range(1,6))

输出结果:

---------- python2.7 ----------
5! = 120

输出完成 (耗时 0 秒) - 正常终止

六、lambda函数

lambda函数用于创建一个匿名函数,函数名未和标识符进行绑定。使用lambda函数可以返回一些简单的运算结果。

lambda函数的格式如下所示:

lambda 变量1,变量2...:表达式

其中,变量列表用于表达式的计算。lambda属于函数,因此变量列表后需要一个冒号。通常把lambda赋值给一个变量,变量就可以作为函数使用。

例如:

#赋值
func = lambda 变量1,变量2...:表达式
#调用
func()

这样就把lambda和变量func绑定在一起了,变量func的名字就是函数名。

例子:使用lambda函数来计算(x + y)*(m - n)

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]

def func():
    x = 1
    y = 2
    m = 3
    n = 4
    sum = lambda x,y:x + y
    print sum
    sub = lambda m,n:m - n
    print sub
    return sum(x,y) * sub (m,n)

print func()

输出结果:

---------- python2.7 ----------
<function <lambda> at 0x00000000022529E8>
<function <lambda> at 0x0000000002252A58>
-3

输出完成 (耗时 0 秒) - 正常终止

注意:

lambda也称之为表达式。lambda中只能使用表达式,不能使用判断、循环等多重语句。

例子:把lambda赋值给一个变量使用,也可以把lambda直接作为函数使用:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
#lambda的函数用法
print(lambda x:-x)(-2)

输出结果:

---------- python2.7 ----------
2

输出完成 (耗时 0 秒) - 正常终止

说明:

定义匿名函数lambda x:-x,用于返回数字的绝对值。

七、generator函数

生成器(generator)的作用是一次产生一个数据项,并把数据项输出。genera函数可以用在for循环中遍历。generator函数所具有的每次返回一个数据项的功能,使得迭代器的性能更佳。

generator函数的定义如下所示:

def 函数名(参数列表):
    ...
    yield 表达式

generator函数的定义和普通函数的定义没什么区别,只要在函数体内使用yield生成数据项即可。

generator函数可以被for循环遍历,而且可以通过next()方法获得yield生成的数据项。

例子:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
#定义generator函数
def func(n):
    for i in range(n):
        yield i
#在for循环中输出
for i in func(3):
    print i
#使用next()输出
r = func(3)
print r.next()
print r.next()
print r.next()
print r.next()

输出结果:

---------- python2.7 ----------
0
1
2
0
1
2
Traceback (most recent call last):
  File "Noname1.py", line 17, in <module>
    print r.next()
StopIteration

输出完成 (耗时 0 秒) - 正常终止

说明:

参数n表示一个数字,该函数依次生成0到n个数字。

最后一次调用r.next(),由于n的值等于3,因此生成3个数字后,已经没有数据可生成。Python解释器抛出异常StopIteration

特别说明:

yield保留字与return语句的返回值和执行原理都不相同。yield生成值并不会终止程序的执行,返回值后程序继续往后执行。return返回值后,程序将中止执行。

例子:yield和return语句的区别。

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2.7
#Author: [email protected]
#yield与return区别
def func(n):
    for i in range(n):
        return i #直接返回i的值,循环语句将终止,整个程序到此结束
def func2(n):
    for i in range(n):
        yield i #循环生成n个数字,循环语句不会被终止

print func(3)
f = func2(3) #yield并没有返回任何值,而是返回了函数func2()的地址
print f
print f.next()
print f.next()

输出结果:

---------- python2.7 ----------
0
<generator object func2 at 0x000000000215A6C0>
0
1

输出完成 (耗时 0 秒) - 正常终止

generator函数可以返回元素的值,而序列也可以获取元素的值。但是两者还是存在很大的区别。generator函数依次只返回一个数据项,占用更少的内存。每次生成数据都要记录当前的状态,便于下一次生成数据。数据的访问时通过next()方法实现的。当访问越界时,generator函数会抛出异常StopIteration。序列一次返回所有的数据,元素的访问时通过索引完成的。当访问越界时,序列提示list index out of range错误。

当程序需要较高的性能或一次只需要一个值进行处理时,使用generator函数。当需要获取一次性一组元素的值时,使用序列。

时间: 2024-10-05 13:07:45

【Python基础学习篇八】Python函数的相关文章

【Python基础学习篇】Python字典

字典(Dictionary)是由"键-值"对组成的集合,字典中的"值"通过"键"来引用. 一.字典的创建 字典由一系列的"键-值"(key-value)对组成,"键-值"对之间用"逗号"隔开,并且被包含在一对花括号中. 创建字典的格式如下: dictionary_name = {key1:value1,key2:value2,...} 如果需要创建一个空的字典,只需要一对花括号即可,如下

【Python基础学习篇】Python基本语法

一.Python的文件类型 Python的文件类型主要分为3种,分别是源代码.字节代码和优化代码. 1.源代码 以py为扩展名 2.字节代码 Python源文件经过编译后生成扩展名为pyc的文件,pyc是编译过的字节文件.这种文件不能使用文本编辑工具打开或修改. 下面这段脚本可以把hello.py文件编译为hello.pyc文件 import py_compile py_compile compile("hello.py") 将此脚本保存为以py为扩展名的文件,运行后即可得到hello

【Python基础学习篇】Python列表

列表(List)通常作为函数的返回类型.列表和元组相似,也是由一组元素组成,列表可以实现添加.删除和查找操作,元素的值可以被修改. 一.列表的创建 列表是由一系列元素组成,所有的元素都被包含在一对方括号中.列表创建后,可以执行添加.删除或修改操作. 列表的创建格式如下所示: list_name = [元素1,元素2,...] 列表的添加可以调用append(),该方法的声明如下所示: append(object) 其中,object可以是元组.列表.字典或任何对象.append()每次添加的新元

【Python基础学习篇】Python元组

元组是Python中内置的一种数据结构.元组由不同的元素组成,每个元素可以存储不同类型的数据,如字符串.数字甚至元组.元组是写保护的,即元组创建后不能再做任何修改操作,元组通常代表一行数据,而元组中的元素代表不同的数据项. 一.元组的创建 Tuple(元组)由一系列元素组成,所有元素被包含在一对圆括号中.创建元组时,可以不指定元素的个数,相当于不定长的数组,但是一旦创建后就不能修改元组的长度. 元组创建的格式如下所示: tuple_name = (元素1,元素2,...) 例子:元组的初始化 t

【Python基础学习篇】Python控制语句

一.结构化程序设计 结构化程序设计是以模块化设计为中心,将待开发的软件系统划分为若干个相互独立的模块. 下图为描述判断摸个数字是属于正数.负数还是零的流程图. 结构化程序设计的主要方法是-自顶向下.逐步细化.把需要解决的问题分成若干个任务来完成,再对每个任务进行设计,逐步细化. 结构化程序设计分为3中结构: 1.顺序结构 2.判断结构 3.循环结构 --------------------------------------------------------------------------

【Python基础学习篇】Python序列

序列是具有索引和切片功能的集合.元组.列表和字符串具有通过索引访问某个具体的值,或通过切片返回一段切片的能力,因此元组.列表和字符串都属于序列. 例子:序列的索引功能 #!/usr/bin/env python # -*- coding=utf-8 -*- #Using GPL v3.3 #Author: [email protected] #索引操作 tuple = ("apple","banana","grape","orange&

【Python基础学习篇九】Python字符串

一.字符串的操作 字符串是Python的一种基本类型,字符串的操作包括字符串的格式化.字符串的截取.过滤.合并.查找等操作. 二.字符串的格式化 Python将若干值插入到带有"%"标记的字符串中,从而可以动态的输出字符串. 字符串的格式化语法如下: "% s" % str1 "%s %s" % (str1,str2) 例子: #!/usr/bin/env python # -*- coding=utf-8 -*- #Using GPL v2.7

【Python基础学习篇十】Python正则表达式(2015-01-01)

一.正则表达式简介 正则表达式用于文本匹配的工具,在源字符串中查找与给定的正则表达式相匹配的部分.一个正则表达式是由字母.数字和特殊字符组成的.正则表达式中有许多特殊的字符,这些特殊字符是构成正则表达式的要素. 1.正则表达式中的特殊字符: 2.正则表达式中的常用限定符: 利用{}可以控制字符重复的次数. 例如,\d{1,4}表示1位到3位的数字: 某些地区的电话号码是8位数,区号也有可能是3位或4位数字. \d{3}-\d{8}|\d{4}-\d{7} 3.限定符与"?"的组合 二.

Python基础学习(八)

Python3 socket Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发 scoket()函数 语法格式如下: socket.socket([soc[type[proto]]]) 参数 soc: 套接字家族可以使AF_UNIX或者AF_INET type: