本篇文章由网友“小黑”投稿发布。所谓函数,就是一段可以被复用的代码块,在Python里要定义一个函数,可以使用如下所示的语法...

    页面导航: 前言:

    本篇文章由网友“小黑”投稿发布。

    本篇文章是根据《Python Tutorial》第14章的内容来写的学习笔记。该英文教程的下载地址如下:

    百度盘地址:http://pan.baidu.com/s/1c0eXSQG

    DropBox地址:点此进入DropBox链接

    Google Drive:点此进入Google Drive链接

定义一个Python函数:

    所谓函数,就是一段可以被复用的代码块,在Python里要定义一个函数,可以使用如下所示的语法:

def functionname(parameters):
	"function_docstring"
	function_suite
	return [expression]


    上面的语法结构中,是通过def关键字来定义一个函数的,functionname表示函数名,括号里的parameters表示函数参数(也就是外部传递给函数的需要处理的数据)。

    def functionname(parameters): 是定义函数时的标准头部结构,该头部结构必须以冒号结尾,冒号后面的部分就是函数体(里面定义了具体的执行代码),函数体中的代码必须相对头部结构往里面进行缩进。

    上面的"function_docstring"字符串对应为函数的说明文档(必须是函数体的第一条语句),这是可选的部分,你可以定义,也可以不定义。在定义完一个函数后,我们可以通过functionname.__doc__语句来获取函数的说明文档。

    function_suite表示具体的可执行代码块。

    通过return关键字可以结束当前函数的执行。return后面可以接一个表达式,这样,函数执行完后,就会将表达式的结果作为整个函数的结果来返回给调用者。如果return后面没有接任何表达式的话,那么就相当于return None,也就是将None对象作为结果返回。

    以下是定义一个函数的简单例子:

def printme(str):
	"This prints a passed string into this function"
	print str
	return


    上面的printme函数需要接受一个参数,它会将该参数以字符串的形式显示输出到终端。

调用Python函数:

    一旦定义好了函数,就可以通过函数名加参数,来调用函数了。

    我们先在test.py文件里写入一段简单的测试代码:

def printme(str):
	"This prints a passed string into this function"
	print str
	return

print printme.__doc__
printme('hello world')
printme('hello Black')


    上面这段代码的执行结果如下:

black@slack:~/test$ python test.py 
This prints a passed string into this function
hello world
hello Black
black@slack:~/test$ 


    通过printme.__doc__就可以获取到printme函数的说明文档信息。通过给printme函数提供参数,就可以将参数以字符串的形式显示出来。

    需要注意的是:由于python是解释执行的语言,def关键字定义函数的操作也是解释执行的,如果在某函数定义之前就调用该函数的话,会产生错误。例如,下面这段代码:

printme('hello')
def printme(str):
	"This prints a passed string into this function"
	print str
	return


    这段代码在执行时,会抛出类似 NameError: name 'printme' is not defined 的错误。也就是在def定义printme函数之前,调用了printme函数的话,会提示printme没有被定义的错误。

通过引用传递参数:

    Python中,所有的函数参数都是通过引用来传递的,也就是说,如果在函数里对参数对象的内容进行了修改的话,函数调用者也会受到参数改变的影响。例如,下面这段代码:

# Function definition is here
def changeme(mylist):
	"This changes a passed list into this function"
	mylist.append([1,2,3,4]);
	print "Values inside the function: ", mylist
	return

# Now you can call changeme function
mylist = [10,20,30];
changeme(mylist);
print "Values outside the function: ", mylist


    上面这段代码的执行结果如下:

black@slack:~/test$ python test.py 
Values inside the function:  [10, 20, 30, [1, 2, 3, 4]]
Values outside the function:  [10, 20, 30, [1, 2, 3, 4]]
black@slack:~/test$ 


    mylist作为参数传递给changeme函数后,在changeme中对列表成员进行了修改,函数返回后,外部的mylist也发生了改变。这就说明传递给changeme函数的是mylist对象的引用。

    如果不想对函数外的mylist产生影响的话,在传递参数时,可以创建一个mylist的拷贝,并将拷贝的引用传递给函数。例如下面这段代码:

# Function definition is here
def changeme(mylist):
	"This changes a passed list into this function"
	mylist.append([1,2,3,4]);
	print "Values inside the function: ", mylist
	return

# Now you can call changeme function
mylist = [10,20,30];
changeme(mylist[:]);
print "Values outside the function: ", mylist


    上面通过mylist[:]创建了一个列表的拷贝,这样函数的执行就不会对外部的mylist产生影响了,执行结果如下:

black@slack:~/test$ python test.py 
Values inside the function:  [10, 20, 30, [1, 2, 3, 4]]
Values outside the function:  [10, 20, 30]
black@slack:~/test$ 


函数参数:

    Python的函数参数也有好几种使用方式,最常见的就是按照函数定义时,参数列表的顺序来传递参数:

# Function definition is here
def printinfo( name, age ):
	"This prints a passed info into this function"
	print "Name: ", name;
	print "Age: ", age;
	return;

# Now you can call printinfo function
printinfo("miki", 50);


    这种方式需要注意两点,一是:参数传递的顺序要与函数定义时的顺序相同。二是:函数定义中的参数都是必须参数,在调用函数时,这些参数一个都不能少,否则会抛出错误,例如下面这段代码:

# Function definition is here
def printinfo( name, age ):
	"This prints a passed info into this function"
	print "Name: ", name;
	print "Age: ", age;
	return;

# Now you can call printinfo function
printinfo("miki");


    这段代码的执行结果如下:

black@slack:~/test$ python test.py 
Traceback (most recent call last):
  File "test.py", line 9, in 
    printinfo("miki");
TypeError: printinfo() takes exactly 2 arguments (1 given)
black@slack:~/test$ 


    printinfo在定义时,需要接受两个参数,那么在调用时,就必须提供两个参数,否则就会抛出上面这个TypeError的错误了。

    当然,我们也可以将上面的age作为可选参数,就可以避免类似的错误发生:

# Function definition is here
def printinfo( name, age = 35 ):
	"This prints a passed info into this function"
	print "Name: ", name;
	print "Age: ", age;
	return;

# Now you can call printinfo function
printinfo("miki");
printinfo("miki", 50);


    上面代码在执行时就不会发生错误了,通过在参数列表里对age设置一个缺省值,那么当调用函数没提供age时,就会使用缺省值了。上面代码的执行结果如下:

black@slack:~/test$ python test.py 
Name:  miki
Age:  35
Name:  miki
Age:  50
black@slack:~/test$ 


    我们其实还可以使用名值对的方式来传递参数:

# Function definition is here
def printinfo( name, age = 35 ):
	"This prints a passed info into this function"
	print "Name: ", name;
	print "Age: ", age;
	return;

# Now you can call printinfo function
printinfo(age = 60, name = "Black");


    上面在调用printinfo函数时,传递了两个名值对:age = 60names = "Black"。等号左边对应参数名,等号右边对应要传递的参数的具体值。使用这种方式的好处在于:参数的传递顺序不需要与函数定义时的完全一致,只需确保名值对里的参数名不出错即可。

    Python函数还支持可变长度的参数,其语法格式如下:

def functionname([formal_args,] *var_args_tuple):
	"function_docstring"
	function_suite
	return [expression]


    可以通过星号来指定一个可变参数元组,如果在formal_args必须参数之后,还传递了更多的参数时,这些参数就都会存储到可变参数元组中。

    下面是可变长度参数的简单例子:

# Function definition is here
def printinfo( arg1, *vartuple ):
	"This prints a variable passed arguments"
	print "Output is: "
	print arg1
	for var in vartuple:
		print var
	return;

# Now you can call printinfo function
printinfo( 10 );
printinfo( 70, 60, 50 );


    当调用printinfo函数时,除了第一个参数外,其余的参数都会存储到vartuple元组中。如果只提供了一个参数的话,那么vartuple就会是一个空元组。这段代码的执行结果如下:

black@slack:~/test$ python test.py 
Output is: 
10
Output is: 
70
60
50
black@slack:~/test$ 


匿名函数:

    Python中还可以使用lambda关键字来创建匿名函数,之所以称之为匿名函数,是因为这些函数没有固定的函数名。其语法格式如下:

lambda [arg1 [,arg2,.....argn]]:expression

    lambda关键字后面直接跟随参数,它可以接任意数量的参数,但是冒号后面的函数体部分只能包含一个表达式,并且表达式里不可以包含print之类的指令。表达式的计算结果会作为整个匿名函数的返回值。

    此外,由于匿名函数没有定义函数名。因此,在使用时,通常需要将它们赋值到某个变量,或者是数组成员中,再由这些变量或数组成员来进行调用。例如下面这段代码:

sum = lambda arg1, arg2: arg1 + arg2
lst = [lambda arg1, arg2: arg1 + arg2, lambda arg1, arg2: arg1 * arg2]

print "value of total: ", sum(10, 20)
print "value of total: ", sum(20, 20)
print "value of 30 + 30: ", lst[0](30,30)
print "value of 30 * 30: ", lst[1](30,30)


    上面这段代码的执行结果如下:

black@slack:~/test$ python test.py
value of total:  30
value of total:  40
value of 30 + 30:  60
value of 30 * 30:  900
black@slack:~/test$ 


    当然我们也可以将匿名函数写入表达式中,并直接调用它,例如下面这段代码:

total = 30 + 40 + (lambda arg1, arg2: arg1 + arg2)(10,20)
print "value of total: ", total


    上面的匿名函数通过括号直接创建出一个匿名函数对象,再向其提供所需的参数即可执行函数里的表达式,表达式的计算结果会作为函数的返回值,并参与到外部的表达式计算中。这段代码的执行结果如下:

black@slack:~/test$ python test.py
value of total:  100
black@slack:~/test$ 


return语句:

    在def关键字定义的函数中,可以通过return关键字来退出函数,并可以根据需要将一个表达式的计算结果返回给调用者。如果return后面没有接任何表达式的话,就相当于return None 。

    下面是一个简单的例子:

# Function definition is here
def sum( arg1, arg2 ):
	"Add both the parameters and return them."
	total = arg1 + arg2
	print "Inside the function : ", total
	return total;

def nothing():
	return;

# Now you can call sum function
total = sum( 10, 20 );
print "Outside the function : ", total
print "nothing function return: ", nothing();


    这段代码的执行结果如下:

black@slack:~/test$ python test.py
Inside the function :  30
Outside the function :  30
nothing function return:  None
black@slack:~/test$ 


变量的作用域:

    Python中的变量也有一个作用范围(或者叫作用域),根据其作用范围,可以分为全局变量与局部变量。全局变量定义在函数外,可以被当前程序中的所有函数访问到。局部变量则定义在函数内,只能被局部变量所在的函数访问到。

    如果局部变量与全局变量同名时,起作用的将会是局部变量。

    下面是一个简单的例子:

total = 0; # This is global variable.
# Function definition is here
def sum( arg1, arg2 ):
	"Add both the parameters and return them."
	total = arg1 + arg2; # Here total is local variable.
	print "Inside the function local total : ", total
	return total;

# Now you can call sum function
sum( 10, 20 );
print "Outside the function global total : ", total


    这段代码的执行结果如下:

black@slack:~/test$ python test.py
Inside the function local total :  30
Outside the function global total :  0
black@slack:~/test$ 


结束语:

    其实天堂也是黑的,只有天使是光明的。

——  和你在一起

    原作者经常提到的《和你在一起》是陈凯歌导演的一部电影,如果没看过的读者,可以看一下。
 
上下篇

下一篇: Python定义和使用模块

上一篇: Python的calendar模块

相关文章

Python列表类型

Python的基本语法

Python基本的I/O操作 (二)

Python词典相关的脚本函数及方法

Python词典类型

Python的安装与使用