一、背景
在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:
while True:
if cpu利用率 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 硬盘使用空间 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 内存占用 > 80%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
腚眼一看上述代码,if条件语句下的内容可以被提取出来公用,如下:
def 发送邮件(内容)
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
while True:
if cpu利用率 > 90%:
发送邮件('CPU报警')
if 硬盘使用空间 > 90%:
发送邮件('硬盘报警')
对于上述的两种实现方式,第二次必然比第一次的重用性和可读性要好,其实这就是函数式编程和面向过程编程的区别:
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
函数式编程最重要的是增强代码的重用性和可读性
二、定义和使用
def 函数名(参数):
...
函数体
...
返回值
函数的定义主要有如下要点:
- def:表示函数的关键字
- 函数名:函数的名称,日后根据函数名调用函数
- 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
- 参数:为函数体提供数据
- 返回值:当函数执行完毕后,可以给调用者返回数据。
1. 返回值
函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。
以上要点中,比较重要有参数和返回值:
def 发送短信():
发送短信的代码...
if 发送成功:
return True
else:
return False
while True:
# 每次执行发送短信函数,都会将返回值自动赋值给result
# 之后,可以根据result来写日志,或重发等操作
result = 发送短信()
if result == False:
记录日志,短信发送失败..
2、参数
- 普通参数
- 默认参数
- 动态参数
普通参数
# ######### 定义函数 #########
# name 叫做函数func的形式参数,简称:形参
def func(name):
print(name)
# ######### 执行函数 #########
# 'wupeiqi' 叫做函数func的实际参数,简称:实参
func('wupeiqi')
默认参数
def func(name, age = 18):
print( "%s:%s" %(name,age))
# 指定参数
func('wupeiqi', 19)
# 使用默认参数
func('alex')
注:默认参数需要放在参数列表最后
动态参数
def func(*args):
print(args)
# 执行方式一
func(11,33,4,4454,5)
# 执行方式二
li = [11,2,2,3,3,4,54]
func(*li)
def func(**kwargs):
print(args)
# 执行方式一
func(name='wupeiqi',age=18)
# 执行方式二
li = {'name':'wupeiqi', age:18, 'gender':'male'}
func(**li)
def func(*args, **kwargs):
print(args)
print(kwargs)
三、局部变量和全局变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
name='lhf'
def change_name():
print('我的名字',name)
change_name()
def change_name():
name='帅了一笔'
print('我的名字',name)
change_name()
print(name)
def change_name():
global name
name='帅了一笔'
print('我的名字',name)
change_name()
print(name)
四、递归调用
在函数内部,可以调用其他函数。如果在调用一个函数的过程中直接或间接调用自身本身
def calc(n):
print(n)
if int(n/2) ==0:
return n
return calc(int(n/2))
calc(10)
输出:
10
5
2
1
#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
import time
person_list=['alex','wupeiqi','yuanhao','linhaifeng']
def ask_way(person_list):
print('-'*60)
if len(person_list) == 0:
return '没人知道'
person=person_list.pop(0)
if person == 'linhaifeng':
return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
print('hi 美男[%s],敢问路在何方' %person)
print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' %(person,person_list))
time.sleep(3)
res=ask_way(person_list)
# print('%s问的结果是: %res' %(person,res))
return res
res=ask_way(person_list)
print(res)
递归问路
递归特性:
-
必须有一个明确的结束条件
-
每次进入更深一层递归时,问题规模相比上次递归都应有所减少
- 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
五、匿名函数
匿名函数就是不需要显式的指定函数
#这段代码
def calc(n):
return n**n
print(calc(10))
#换成匿名函数
calc = lambda n:n**n
print(calc(10))
匿名函数主要是和其它函数搭配使用的呢,如下
l=[3,2,100,999,213,1111,31121,333]
print(max(l))
dic={'k1':10,'k2':100,'k3':30}
print(max(dic))
print(dic[max(dic,key=lambda k:dic[k])])
res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
print(i)
输出
1
25
49
16
64
六、内置函数
- map
array=[1,3,4,71,2]
ret=[]
for i in array:
ret.append(i**2)
print(ret)
#如果我们有一万个列表,那么你只能把上面的逻辑定义成函数
def map_test(array):
ret=[]
for i in array:
ret.append(i**2)
return ret
print(map_test(array))
#如果我们的需求变了,不是把列表中每个元素都平方,还有加1,减一,那么可以这样
def add_num(x):
return x+1
def map_test(func,array):
ret=[]
for i in array:
ret.append(func(i))
return ret
print(map_test(add_num,array))
#可以使用匿名函数
print(map_test(lambda x:x-1,array))
#上面就是map函数的功能,map得到的结果是可迭代对象
print(map(lambda x:x-1,range(5)))
map函数
- filter
#电影院聚集了一群看电影bb的sb,让我们找出他们
movie_people=['alex','wupeiqi','yuanhao','sb_alex','sb_wupeiqi','sb_yuanhao']
def tell_sb(x):
return x.startswith('sb')
def filter_test(func,array):
ret=[]
for i in array:
if func(i):
ret.append(i)
return ret
print(filter_test(tell_sb,movie_people))
#函数filter,返回可迭代对象
print(filter(lambda x:x.startswith('sb'),movie_people))
--------------
name_dic=[
{'name':'alex','age':1000},
{'name':'wupeiqi','age':10000},
{'name':'yuanhao','age':9000},
{'name':'linhaifeng','age':18},
]
res = filter(lambda x:x['age'] <= 18,name_dic)
print(list(res))
filter函数
3.reduce
l = [1,2,3,100]
def gn(x,y):
return x*y
def reduce_test(sd,lis,init=None):
if init is None:
res = lis.pop(0)
else:
res = init
for i in lis:
res = sd(res,i)
return res
print(reduce_test(gn,l,100))
------------------------
from functools import reduce
res = reduce(lambda x,y:x+y,l,100)
print(res)
总结:
- map:理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样
- filter遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来
- reduce:处理一个序列,然后把序列进行合并操作
# print(abs(1)) #绝对值
# print(all([1,23,''])) #是否都为真
# print(all('')) #为真
# print(any([1,3,''])) #只要有一个为真,即为真
# print(bin(10))#10进制->2进制
# print(hex(12))#10进制->16进制
# print(oct(12))#10进制->8进制
#空、NONE、0、的布尔值为false,其余都为true
# print(bool(''))
# name = '你好'
# print(bytes(name,encoding='utf-8')) #转换为字节,并指定字符编码格式
# print(bytes(name,encoding='utf-8').decode('utf-8'))
# print(divmod(10,3)) #做除法,显示商和余数,可用于分页判断
#可hash的数据类型即不可变数据类型,不可hash的数据类型即可变数据类型
# name = 'lingxd'
# print(hash(name))
# print(hash(name))
#
# print(help(all))
# print(isinstance(1,int)) #判断 数据类型是否正确
# print(isinstance(1,str))
# print(globals()) #全局变量
# print(locals()) #局部变量
# l = [1,2,34]
# print(max(l)) #输出最大值
# print(min(l)) #输出最小值
# print(list(zip(('a','b','c'),(1,2,3))))
#
# p = {'name':'lingxd','age':25,'gender':'man'}
# print(list(zip((p.keys()),(p.values()))))
#
# print(list(zip((['a','b']),('12345'))))
# l={'alex_age':18,'wupei_age':20,'zsc_age':100,'lhf_age':30}
#
# print(max(zip((l.values()),(l.keys()))))
# people=[
# {'name':'alex','age':1000},
# {'name':'wupei','age':10000},
# {'name':'yuanhao','age':9000},
# {'name':'linhaifeng','age':18},
# ]
#
# print(max(people,key=lambda dic:dic['age']))
# print(chr(97)) #转换为字符编码
# print(ord('a')) #反转字符编码
#
# l = [1,2,3,4,5]
# print(list(reversed(l))) #反转,不会修改原数据
#
# print(pow(3,2)) #相当于3**2
# print(pow(3,2,2)) #相当于3**2 %2取余数
# print(round(3.6)) #四舍五入
#
# l = 'lingxd'
# s1 = slice(1,3) #相当于切片操作,定义切片
# print(l[s1])
# l = [3,2,5,9,11]
# print(sorted(l)) #排序,从小到大
#
# people=[
# {'name':'alex','age':1000},
# {'name':'wupei','age':10000},
# {'name':'yuanhao','age':9000},
# {'name':'linhaifeng','age':18},
# ]
#
# print(sorted(people,key=lambda dic:dic['age']))
# name_dic={
# 'abyuanhao': 11900,
# 'alex':1200,
# 'wupei':300,
# }
#
# print(sorted(zip((name_dic.values()),(name_dic.keys()))))
# l=[1,2,3,4]
# print(sum(l)) #求和
# print(sum(range(5)))
# print('123',type('123')) #显示类型
# s = '123'
# if type(s) is str:
# s = int(s)
# res = s+1
# print(res)
# def heh():
# s = 'heheh'
# print(locals())
# print(vars())
#
# heh()
#
# print(vars(type))