1 函数定义、调用
以 def 关键字开头,后接函数标识符名称和圆括号 ();圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明;函数内容以冒号起始,并且缩进。
return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
def print_fozu() :
print " _ooOoo_ "
print " o8888888o "
print " 88 . 88 "
print " (| -_- |) "
print " O\\ = /O "
print " ____/`---'\\____ "
print " . ' \\| |// `. "
print " / \\||| : |||// \\ "
print " / _||||| -:- |||||- \\ "
print " | | \\\\\\ - /// | | "
print " | \\_| ''\\---/'' | | "
print " \\ .-\\__ `-` ___/-. / "
print " ___`. .' /--.--\\ `. . __ "
print " ."" '< `.___\\_<|>_/___.' >'"". "
print " | | : `- \\`.;`\\ _ /`;.`/ - ` : | | "
print " \\ \\ `-. \\_ __\\ /__ _/ .-` / / "
print " ======`-.____`-.___\\_____/___.-`____.-'====== "
print " `=---=' "
print " "
print " ............................................. "
print_fozu()
2 函数参数
In [1]: def add(a,b):
...: c=a+b
...: print("%d+%d=%d"%(a,b,c))
...:
In [2]: add(8,10)
8+10=18
函数的参数传递:
不可变类型:如整数、字符串、元组。如fun(a),传递的是a的值,不影响a本身。在fun内部修改 a 的值,只是修改另一个复制的对象,不会影响 a。
可变类型:如列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响。
参数类型:
必须参数:以正确的顺序传入函数。调用时的数量必须和声明时的一样。
关键字参数:函数调用使用关键字参数来确定传入的参数值。调用时参数的顺序与声明时可以不一致。
默认参数:调用函数时,如果没有传递参数,则会使用默认参数。
不定长参数:加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。加了两个星号 ** 的参数会以字典的形式导入。单独出现星号 * 后的参数必须用关键字传入。
#必须参数
def print_me( str ):
print (str)
return
print_me() #此处必须传入一个参数,否则出现错误
#关键字参数
def print_info( name, age ):
print ("名字: ", name)
print ("年龄: ", age)
return
printinfo( age=23, name="hill" ) #顺序可以不一致
#默认参数
def print_info( name, age = 23 ): #带默认参数的定义只能放在后面(右边)
print ("名字: ", name)
print ("年龄: ", age)
return
print_info( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )
名字: runoob
年龄: 50
------------------------
名字: runoob
年龄: 35
#不定长参数
def printinfo( arg1, *vartuple ):
print ("输出: ")
print (arg1)
print (vartuple)
printinfo( 70, 60, 50 )
输出:
70
(60, 50)
#不定长参数带两个*
def printinfo( arg1, **vardict ):
print ("输出: ")
print (arg1)
print (vardict)
printinfo(1, a=2,b=3)
输出:
1
{'a': 2, 'b': 3}
注意 * 和 ** 的区别:
In [1]: def test(a,b,c=3,*args,**kwargs):
...: print(a);print(b);print(c);print(args);print(kwargs)
...:
In [2]: A=(4,5,60);B={'k1':1,'k2':2}
In [3]: test(1,2,3,A,B)
1
2
3
((4, 5, 60), {'k1': 1, 'k2': 2})
{}
In [4]: test(1,2,3,*A,**B) #表示拆包
1
2
3
(4, 5, 60)
{'k1': 1, 'k2': 2}
3 匿名函数
使用 lambda 来创建匿名函数
lambda [arg1 [,arg2,.....argn]]:expression
#lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数
sum = lambda arg1, arg2: arg1 + arg2
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
相加后的值为 : 30
相加后的值为 : 40
In [1]: data=[ {'name':'huang','age':23},{'name':'wen','age':21},{'name':'min','age':20} ]
In [2]: data.sort(key=lambda x:x['name'])
In [3]: data
Out[3]:
[{'name': 'huang', 'age': 23},
{'name': 'min', 'age': 20},
{'name': 'wen', 'age': 21}]
In [4]: data.sort(key=lambda x:x['age'])
In [5]: data
Out[5]:
[{'name': 'min', 'age': 20},
{'name': 'wen', 'age': 21},
{'name': 'huang', 'age': 23}]
In [7]: def test(a,b,fun):
...: result = fun(a,b)
...: return result
...:
In [8]: num =test(1,2,lambda x,y:x+y)
In [9]: num
Out[9]: 3
In [10]: num =test(1,2,lambda x,y:x-y)
In [11]: num
Out[11]: -1
4 变量作用域
L (Local) 局部作用域; E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域;B (Built-in) 内建作用域
以 L –> E –> G –>B 的规则查找
只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
num = 1
def fun1():
global num # global 关键字声明,否则在函数内num为新建的num(列表和字典除外!!)
print(num)
num = 123
print(num)
fun1()
print(num)
1
123
123
In [1]: def outer():
...: num=10
...: def inner():
...: num=100
...: print(num)
...: inner()
...: print(num)
...:
In [2]: outer()
100
10
In [3]: def outer():
...: num=10
...: def inner():
...: nonlocal num # nonlocal 关键字修改嵌套作用域,修改外部变量的值
...: num=100
...: print(num)
...: inner()
...: print(num)
...:
In [4]: outer()
100
100
5 return多个值
def test():
a=1;b=2;c=3
#1 用列表封装
d=[a,b,c]
return d
#2 直接返回列表
return [a,b,c]
#3 返回元组
return (a,b,c) #or return a,b,c