函数是组织好的,可重复使用的,用来实现单一或相关功能的代码段.
函数能提高应用的模块性,和代码的重复利用率.
Python提供了很多内建函数,比如print().你也可以自己创建函数,这被叫做自定义函数.
定义一个函数
你可以定义一个有自己想要的功能的函数,以下是简单的规则:
函数的代码块以 def 关键字开头,后接函数标识符名称和园括号().
任何传入参数和自变量必须放在园括号中间,园括号之间可以用于定义参数.
函数的第一行语句可以选择性的使用文档字符串--用于存放函数说明.
函数内容以冒号起始,并且缩进.
* return [表达式] 结束函数,选择性的返回一个值给调用方.不带表达式的return相当于返回None.
自定义函数的语法
def functionname( parameters):
"函数_文档字符串"
function_suite
return [expression]
默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的.
实例
以下为一个简单的python函数,它将一个字符串作为传入参数,再打印到标准显示设备上.
def printme(str):
"打印传入的字符串到标准显示设备上"
print str
return
函数调用
定义一个函数只给了函数一个名称,制定了函数包含的参数,和代码快结构.
这个函数的基本结构完成以后末,可以通过另一个函数调用执行,也可以直接从Python提示符执行.
如下示例调用了printme()函数:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
#定义函数
def printme(str):
"打印任何传入的字符串"
print str
return
#调用函数
printme("我要调用用户自定义函数")
printme("再次调用这个函数")
示例结果为:
我要调用用户自定义函数
再次调用这个函数
参数传递
在python中,类型属于对象,变量是没有类型的:
a = [1, 2, 3]
a = "abcd"
以上代码中,[1, 2, 3]是List类型的,"abcd"是String类型的,而变量a是没有类型的,她仅仅是一个对象的引用(一个指针),可以使List类型对象,也可以指向String类型对象.
可更改(mutable)和不可更改(immutable)对象
在python中,string,tuples和numbers是不可更改的对象,而list,dict等则是可以修改的对象.
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个int对象10,再让a指向它,而5被丢弃,不是改变a的值,相当于生成了a.
可变类型:变量赋值 la=[1,2,3,4]后再赋值 la=[2]=5 则是将list la的第二个元素值更改,本身la没有改动,只是其内部的一部分值被修改了.
Pyhton函数的参数传递:
- 不可变类型:类似c++的值传递,如整数,字符串,元组.比如fun(a) ,传递的只是a的值,没有影响a对象本身.比如在 fun(a) 内部修改a的值,只是修改另一个复制的对象,不会影响a本身.
- 可变类型:类似c++的引用传递,如列表,字典.比如 fun(la) 是将la真正的值传过取,修改后fun外部的la也会受影响.
python中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象.
python传不可变对象实例:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
def ChangeInt(a):
a = 10
b = 2
ChangeInt(b)
print b # 结果是2
示例中的int对象2,指向它的变量b,在传递给ChangeInt函数时,按传值的方式赋值了变量b,a和b都指向了同一个int对象,在a=10时,则新生成一个int对象10,并让a指向它.
python传可变对象实例
#!/usr/bin/python
#-*- coding: UTF-8 -*-
#定义函数
def changeme(mylist):
"修改传入的列表"
mylist.append([1,2,3,4])
print "函数内取值: ", mylist
return
#调用changme()函数
mylist = [10,20,30]
changme(mylist)
print "函数外取值: ", mylist
示例中传入函数的和在末尾添加新内容的对象用的是同一个引用,结果为下:
函数内取值: [10,20,30,[1,2,3,4]]
函数外取值: [10,20,30,[1,2,3,4]]
函数的参数
以下是调用函数时可使用的正式参数类型:
1. 必备参数
2. 关键字参数
3. 默认参数
4. 不定长参数
1.必备参数
必备参数以正确的顺序传入函数.调用时的数量必须和声明时的一样.
调用printme()函数,你必须传入一个参数,否则会出现语法错误.
2.关键字参数
关键字参数和函数调用紧密,函数调用使用关键字参数来确定传入的参数.
使用关键字参数允许函数调用参数的顺序与声明时不一致,因为python解释器能够用参数名匹配参数值.
以下示例在pringme()函数调用时使用参数名:
def printme(str):
print str
return
printme(str = "my string")
示例结果为:
my string
关键字参数的传递顺序并不重要
3.缺省参数
调用函数时,缺省参数的值如果没有传入,则被认为是默认值,下例会打印默认的age,如果age没有被传入:
def printinfo(name, age = 20):
print "name: ", name
print "age: ", age
return
printinfo(age=50,name="jack")
printinfo(name="jack")
示例结果为:
name:jack
age:50
name:jack
age=20
4.不定长参数
有时你可能需要一个函数能处理闭当初声明时更多的参数.这些参数叫做不定长参数,和上述2中参数不同,声明时不会命名.基本语法如下:
def functionname([formal_args], *var_args_tuple):
function_suite
return [expression]
加了星号(*)的变量名会存放所有未命名的变量参数.选择不多传参数也可.如下示例:
def printinfo(arg1, *valtuple)
print "输出: "
print arg1
for var in vartuple:
print var
return
printinfo(10)
printinfo(70,80,90)
示例结果为:
输出:
10
输出:
70
80
90
匿名函数
python使用lambda来创建匿名函数. * lambda只是一个表达式,函数体闭def简单很多. * lambda的主题是一个表达式,而不是一个代码块.仅仅能在lambda表达式中封装有限的逻辑进去. * lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间的参数. * 虽然lambda函数看起来只能写一行,却不等同于c或c++的内敛函数,后者的目的是调用小函数时不占用栈和内存从而增加运行效率.
匿名函数语法
lambda函数的语法只包含一个语句,如下:
lamda [arg1 [,arg2,....argn]]:expression
如下示例:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
sum = lambda arg1,arg2:arg1+arg2
print "相加后的结果: ", sum(10, 20)
print "相加后的结果: ", sum(20, 20)
示例结果为:
相加后的结果: 30
相加后的结果: 40
return语句
return [表达式] 退出函数,选择性的向调用方返一个表达式.不带参数值的return语句返回None.
#!/usr/bin/python
#-*- coding: UTF-8 -*-
def sum(arg1,arg2):
total = arg1 + arg2
print "函数内 : ", total
return total
total = sum(10, 20)
示例结果为:
函数内 : 30
变量作用域
一个程序的所有的变量并不是在哪个位置都可以访问的.访问权限决定这个变量是在哪里赋值的.
变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量.
两种最基本的变量作用域如下:
1. 全局变量
2. 局部变量
全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的变量拥有全局作用域.
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问.
调用函数时,所有在函数内声明的变量名称都将加入到作用域中.如下:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
total = 0 #这是一个全局变量
def sum(arg1, arg2):
total = arg1 +arg2 # total在这里是局部变量
print "函数内是局部变量: ",total
return total
#调用函数
sum(10, 20)
print "函数外是全局变量: ", total
示例结果为:
函数内是局部变量: 30
函数外是全局变量: 0