阅读目录
一 数学定义的函数与python中的函数
二 为何使用函数
背景提要
三 函数和过程
四 函数参数
五 局部变量和全局变量
六 前向引用之‘函数即变量‘
七 嵌套函数和作用域
八 递归
九 匿名函数
十 函数式编程
十一 内置函数
十二 本节作业
一 数学定义的函数与python中的函数
初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数。自变量x的取值范围叫做这个函数的定义域
例如y=2*x
python中函数定义:函数是逻辑结构化和过程化的一种编程方法。
1 python中函数定义方法:
2
3 def test(x):
4 "The function definitions"
5 x+=1
6 return x
7
8 def:定义函数的关键字
9 test:函数名
10 ():内可定义形参
11 "":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
12 x+=1:泛指代码块或程序处理逻辑
13 return:定义返回值
调用运行:可以带参数也可以不带
函数名()
补充:
1.编程语言中的函数与数学意义的函数是截然不同的俩个概念,编程语言中的函数是通过一个函数名封装好一串用来完成某一特定功能的逻辑,数学定义的函数就是一个等式,等式在传入因变量值x不同会得到一个结果y,这一点与编程语言中类似(也是传入一个参数,得到一个返回值),不同的是数学意义的函数,传入值相同,得到的结果必然相同且没有任何变量的修改(不修改状态),而编程语言中的函数传入的参数相同返回值可不一定相同且可以修改其他的全局变量值(因为一个函数a的执行可能依赖于另外一个函数b的结果,b可能得到不同结果,那即便是你给a传入相同的参数,那么a得到的结果也肯定不同)
2.函数式编程就是:先定义一个数学函数(数学建模),然后按照这个数学模型用编程语言去实现它。至于具体如何实现和这么做的好处,且看后续的函数式编程。
二 为何使用函数
背景提要
现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码
1 while True:
2 if cpu利用率 > 90%:
3 #发送邮件提醒
4 连接邮箱服务器
5 发送邮件
6 关闭连接
7
8 if 硬盘使用空间 > 90%:
9 #发送邮件提醒
10 连接邮箱服务器
11 发送邮件
12 关闭连接
13
14 if 内存占用 > 80%:
15 #发送邮件提醒
16 连接邮箱服务器
17 发送邮件
18 关闭连接
def 发送邮件(内容)
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
while True:
if cpu利用率 > 90%:
发送邮件(‘CPU报警‘)
if 硬盘使用空间 > 90%:
发送邮件(‘硬盘报警‘)
if 内存占用 > 80%:
发送邮件(‘内存报警‘)
总结使用函数的好处:
1.代码重用
2.保持一致性,易维护
3.可扩展性
三 函数和过程
过程定义:过程就是简单特殊没有返回值的函数
这么看来我们在讨论为何使用函数的的时候引入的函数,都没有返回值,没有返回值就是过程,没错,但是在python中有比较神奇的事情
1 def test01():
2 msg=‘hello The little green frog‘
3 print msg
4
5 def test02():
6 msg=‘hello WuDaLang‘
7 print msg
8 return msg
9
10
11 t1=test01()
12
13 t2=test02()
14
15
16 print ‘from test01 return is [%s]‘ %t1
17 print ‘from test02 return is [%s]‘ %t2
总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,
所以在python中即便是过程也可以算作函数。
1 def test01():
2 pass
3
4 def test02():
5 return 0
6
7 def test03():
8 return 0,10,‘hello‘,[‘alex‘,‘lb‘],{‘WuDaLang‘:‘lb‘}
9
10 t1=test01()
11 t2=test02()
12 t3=test03()
13
14
15 print ‘from test01 return is [%s]: ‘ %type(t1),t1
16 print ‘from test02 return is [%s]: ‘ %type(t2),t2
17 print ‘from test03 return is [%s]: ‘ %type(t3),t3
总结:
返回值数=0:返回None
返回值数=1:返回object
返回值数>1:返回tuple
四 函数参数
1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)
4.默认参数
5.参数组
五 局部变量和全局变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
1 name=‘lhf‘
2
3 def change_name():
4 print(‘我的名字‘,name)
5
6 change_name()
7
8
9 def change_name():
10 name=‘帅了一笔‘
11 print(‘我的名字‘,name)
12
13 change_name()
14 print(name)
15
16
17
18 def change_name():
19 global name
20 name=‘帅了一笔‘
21 print(‘我的名字‘,name)
22
23 change_name()
24 print(name)
六 前向引用之‘函数即变量‘
1 def action():
2 print ‘in the action‘
3 logger()
4 action()
5 报错NameError: global name ‘logger‘ is not defined
6
7
8 def logger():
9 print ‘in the logger‘
10 def action():
11 print ‘in the action‘
12 logger()
13
14 action()
15
16
17 def action():
18 print ‘in the action‘
19 logger()
20 def logger():
21 print ‘in the logger‘
22
23 action()
七 嵌套函数和作用域
看上面的标题的意思是,函数还能套函数?of course
1 name = "Alex"
2
3 def change_name():
4 name = "Alex2"
5
6 def change_name2():
7 name = "Alex3"
8 print("第3层打印",name)
9
10 change_name2() #调用内层函数
11 print("第2层打印",name)
12
13
14 change_name()
15 print("最外层打印",name)
此时,在最外层调用change_name2()会出现什么效果?
没错, 出错了, 为什么呢?
作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变
1 例一:
2 name=‘alex‘
3
4 def foo():
5 name=‘lhf‘
6 def bar():
7 print(name)
8 return bar
9
10 func=foo()
11 func()
12
13
14 例二:
15 name=‘alex‘
16
17 def foo():
18 name=‘lhf‘
19 def bar():
20 name=‘wupeiqi‘
21 def tt():
22 print(name)
23 return tt
24 return bar
25
26 func=foo()
27 func()()
八 递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
1 def calc(n):
2 print(n)
3 if int(n/2) ==0:
4 return n
5 return calc(int(n/2))
6
7 calc(10)
8
9 输出:
10 10
11 5
12 2
13 1
递归问路
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html
二分查找
九 匿名函数
匿名函数就是不需要显式的指定函数
1 #这段代码
2 def calc(n):
3 return n**n
4 print(calc(10))
5
6 #换成匿名函数
7 calc = lambda n:n**n
8 print(calc(10))
1 l=[3,2,100,999,213,1111,31121,333]
2 print(max(l))
3
4 dic={‘k1‘:10,‘k2‘:100,‘k3‘:30}
5
6
7 print(max(dic))
8 print(dic[max(dic,key=lambda k:dic[k])])
1 res = map(lambda x:x**2,[1,5,7,4,8])
2 for i in res:
3 print(i)
4
5 输出
6 1
7 25
8 49
9 16
10 64
十 函数式编程
11 高阶函数
满足俩个特性任意一个即为高阶函数
1.函数的传入参数是一个函数名
2.函数的返回值是一个函数名
map函数
reduce函数
filter函数
总结
十一 内置函数
View Code
内置参数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii
本文出自 “游走的风” 博客,转载请与作者联系!
原文地址:http://774148515.blog.51cto.com/10937712/1900367