一、函数的简介
简单来说,函数就是一个有组织性的,能实现对应功能代码段。
函数的作用是方便重复使用,实现相关功能,使代码模块化,提高代码可读性。
Python提供了丰富的内置函数,但是同样的,用户可以自己编写函数,这被叫做用户自定义函数。
二、函数的定义
定义函数的规则:
- 函数代码块以 def 关键词开头,后接函数名和圆括号()。
- 圆括号之间可以用于定义参数。任何传入参数和自变量必须放在圆括号中间。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。
- 不带表达式的return或者不写return则于返回 None。
1.定义一个空函数
def fun():
pass
return
2.定义一个普通函数
def 函数名(形参):
函数体
return 返回值
三、函数的调用
1.调用内置函数
Python常见的内置函数
abs() #绝对值
cmp() #比较
len() #长度
type() #类型
sorted() #排序
#数据类型转换函数:
int()
long()
float()
complex()
bool()
str()
list()
tuple()
dict()
set()
调用len函数
In [78]: len("hello")
Out[78]: 5
2.调用用户自定义函数
In [79]: def mul(N1,N2):
....: return N1 * N2
....:
In [80]: mul(3,4)
Out[80]: 12
四、函数的参数传递
在 Python 中,类型属于对象,变量是没有类型的:
a=[1,2,3]
a="string"
以上代码中,[1,2,3] 是 list 类型,”string” 是 string 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是 list 类型对象,也可以指向 string 类型对象。
1.可更改(mutable)与不可更改(immutable)对象(也叫做可变与不可变类型)
在 Python 中,strings,tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
可变类型:变量赋值 li=[1,2,3,4] 后再赋值 li[2]=5 则是将 list li 的第三个元素值更改,本身li没有动,只是其内部的一部分值被修改了。
2.Python 函数的参数传递:
不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
Python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
Eg:传不可变类型参数与可变类型参数实例:
不可变类型:
In [1]: def fun1(a):
...: a = 3
...:
In [2]: b = 4
In [3]: fun1(b)
In [4]: b
Out[4]: 4
可变类型:
In [5]: def fun2(li):
...: li.append('data')
...: print li
...:
In [6]: li = ['num','str']
In [7]: fun2(li)
['num', 'str', 'data']
五、函数的参数
定义函数时的参数叫形式参数,调用函数时的参数叫实际参数。
函数的形式参数有:必选参数,默认参数,可变参数,关键字参数。
1.必选参数
必备参数必须以正确的顺序传入函数,传参的数量也必须和声明时的一样。
def fun(a): #a为必选参数
print a
fun() #未传参
##########执行结果###########
TypeError: fun() takes exactly 1 argument (0 given) #报错
############修改#############
def fun(a):
print a
fun("A")
##########执行结果###########
A
2.默认参数
调用函数时,默认参数的值如果没有传入,则以默认值执行,若传入,则以传入参数执行。
def fun(a = 2):
print a
fun() #未传参
##########执行结果###########
2
##########修改传参###########
def fun(a = 2):
print a
fun(3) #传参
##########执行结果###########
3
默认参数有一点需要注意:
先用代码测试:
def fun(li = []):
li.append("this is a text")
return li
print fun()
print fun()
结果如下:
['this is a text']
['this is a text', 'this is a text']
发现第二次调用函数时,函数值已经发生改变,因此函数的默认参数发生变化,因此最好不使用可变数据类型作为函数的默认参数。
3.可变参数
可变参数也叫不定长参数,即可以传入任意多个参数,而只需声明一次。
def fun(*args):
print args
fun(2)
fun(3,4)
fun('hello','world','!')
##########执行结果###########
(2,) #发现返回值是一个元组
(3, 4)
('hello', 'world', '!')
4.关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
def fun(name,likes):
print "%s likes %s " %(name,likes)
fun(likes = 'music',name = 'A')
fun('movies','B')
##########执行结果###########
A likes music
movies likes B
也可以不定长传入关键字参数:
关键字参数允许传入 0 个或任意个含参数名的参数
这些关键字参数在函数内部自动组装为一个字典
def fun(**kwargs):
print kwargs
fun(likes = 'music',name = 'A')
##########执行结果###########
{'likes': 'music', 'name': 'A'} #发现返回值是一个字典
5.组合参数
当然,函数可以一次使用多个类型的参数,这叫做组合参数。
参数组合时定义的的顺序必须是:必选参数 > 默认参数 > 可变参数 > 关键字参数。
def fun(a, b=0, *c, **d): #a是必选参数,b是默认参数,c是可变参数,d是关键字参数
print a, b, c, d
fun(1)
fun(1, 2)
fun(1, 2, 3)
fun(1, 2, 3, 4)
fun(1, 2, 3, (4, 5))
fun(1, 2, 3, [4, 5])
fun(1, 2, 3, {4, 5})
fun(1, 2, 3, 4, x=1, y=2)
执行的结果:
1 0 () {}
1 2 () {}
1 2 (3,) {}
1 2 (3, 4) {}
1 2 (3, (4, 5)) {}
1 2 (3, [4, 5]) {}
1 2 (3, set([4, 5])) {}
1 2 (3, 4) {'y': 2, 'x': 1}
六、变量作用域
一个程序的所有的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里定义的。
变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量名称。
两种最基本的变量作用域如下:
- 全局变量
- 局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
下面用代码演示局部变量与全局变量的不同之处:
a = 10
def fun():
a = 100
print a
#################执行结果#################
10
#########################################
a = 10
def fun():
a = 100
fun()
print a
#################执行结果#################
10 #发现结果依然为10
#########################################
a = 10
def fun():
global a #声明a是全局变量
a = 100 #再给a赋值
# global a = 100 #错误的做法
fun()
print a
#################执行结果#################
100 #发现结果变为100
七、匿名函数
1.匿名函数特点:
- 匿名函数的关键字为 lambda,,冒号前面是形式参数, 冒号后面是返回值
- 匿名函数的形式参数可以是:必选, 默认, 可变, 关键字参数
- lambda只是一个表达式,函数体比def简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
2.定义一个匿名函数
lambda函数只包含一个语句,如下:
lambda 任意参数:表达式 #表达式就是对参数的操作
3.匿名函数的使用:
In [8]: mul = lambda x,y : x * y
In [9]: mul(3,5)
Out[9]: 15
In [10]: fun = lambda x, y=2, *args, **kwargs: (x * y, args, kwargs)
In [11]: fun(2, 3, 4, 5, 6, 7, a=1, b=2, c=3)
Out[11]: (6, (4, 5, 6, 7), {'a': 1, 'b': 2, 'c': 3})