页面导航:
前言:
本篇文章由网友“小黑”投稿发布。
本篇文章是根据《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 = 60 与
names = "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$
|
结束语:
其实天堂也是黑的,只有天使是光明的。
—— 和你在一起
原作者经常提到的《和你在一起》是陈凯歌导演的一部电影,如果没看过的读者,可以看一下。