函数的理解
面向过程:根据业务逻辑从上到下垒代码
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
函数作用是你的程序有良好的扩展性、复用性。
同样的功能要是用3次以上的话就建议使用函数。
特殊理解:
函数可以理解为一个一个的功能块,你把一个大的功能拆分成一块一块的,用某项功能的时候就去调用某个功能块即可!
函数可以理解为:乐高积木,给你一块一块的,你可以用这些积木块组成你想要的任何功能!
函数可以调用函数!主函数的作用就是把函数进行串联、调用!函数本身是不能自己执行的如果不调用就永不执行!
#--------------------------------------------------- def func1(): pass def func2(): pass def func3(): pass def func4(): pass func1() func2() func3() func4() if __name__ == '__main__': #调用上面的函数,判断了、循环了调用等! #函数里也可以调用函数例子:def func4(): #__name__ 这个是用来判断,如果你是把这个程序当模块导入的话它的__name__就等于这个程序的文件名,如果是手动执行这个脚本比如:python test.py 那么__name__就等于__main__ 所以,我们可以用他来做判断,如果你是手动执行我就调用函数执行if下面的语句,如果你是调用模块下面的if判断后面的语句就不执行!仅当模块使用! #如果函数当模块导入的时候,他导入的是函数的名称,内容没有被导入,当你去调用的时候他才会导入函数里的信息。
自定义函数
一、背景
在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发工程中比较常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:
while True: if cpu利用率 > 90 %: # 发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90%: # 发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 >80%: # 发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接
上面的代码就是面向过程的编程,但是如果报警多了的话成百的代码需要如何操作呢?复制粘贴就会显得自己low,该如何编写呢,请看下面的代码:
def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
第二个必然比第一个的重用性和可读性要好,其实就是函数式编程和面向过程编程的区别:
● 面向过程:更具需求一行一行垒加代码!逻辑乱、并切代码重复、不易修改重用性差!
● 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
● 面向对象:对函数进行分类和封装,让开发"更快更好更强"
二、函数式编程
函数式编程最重要的是增强代码的重用性和可读性:
# 语法 def 函数(参数1,参数2,参数3,....): ' ' '注释' ' ' 函数体 return 返回的值 #函数名的定义要能反映其意义
函数的定义主要有如下要点:
● def 表示函数的关键字
● 函数名:函数的名称,日后根据函数名调用函数
● 参数:为函数体提供数据
● 函数体:函数中进行一系列的逻辑计算,如,发送邮件、计算出[11,22,45,56,45,]中的最大数等....
● 返回值:当函数执行完毕后,可以给调用者返回数据。
函数使用的原则:先定义,后调用
函数即"变量","变量"必须先定义后引用,未定义而直接函数,就相当于在引用一个不存在的变量名 #测试一 def func(): print('from foo') bar() func() #报错 #测试二 def abc(): print('from abc') def func(): print('from func') abc() func() #正常 #测试三 def func(): print('from func') abc() def abc(): print('from abc') func() #不会报错 #结论:函数的使用,必须遵循原则:先定义,后调用 #我们在使用函数时,一定要明确的区分定义阶段和调用阶段 #定义阶段: def func(): print('from func') abc() def abc(): print('from abc') #调用阶段 func()
函数在定义阶段都干了哪些事?
#只检测语法,不执行代码 也就说,语法错误在函数定义阶段就会检测出来,而代码的逻辑错误只有在执行的时候才会知道
定义函数的三种形式
#1、无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印 #2、有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值 #3、空函数:设计代码结构
1、返回值
函数式一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。
def test(): ''' 2*x+1 :param x:整形数字 :return: 返回计算结果 ''' x=3 y=2*x+1 return y a = test() print(a)
def 发送短信(): 发送短信的代码..: if 发送成功: return True else: return False while True: # 每次执行发送短信函数,都会将返回值自动赋值给result # 之后,可以根据result来写日志,或重发等操作 result = 发送短信() if result == False: 记录日志,短信发送失败....
2、参数
1、形参与实参
#形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
2、具体应用
#1、位置参数:按照从左到右的顺序定义的参数 位置形参:必选参数 位置实参:按照位置给形参传值 #2、关键字参数:安装key=value的形式定义的实参 无需按照位置为形象传值 注意的问题: 1、关键字实参必须在位置实参右面 2、对同一个形参不能重复传值 #3、默认参数:形参在定义时就已经为其赋值 可以传值也可以不传值,经常需要变得参数定义成位置形参,变成较小的参数定义成默认参数(形参) 注意的问题: 1、只在定义时赋值一次 2、默认参数的定义应该在位置形参右面 3、默认参数通常应该定义成不可变类型 #4、可变长参数: 可变长指的是实参值的个数不固定 而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs # ########### *args #################### def foo(x,y,*args): print(x,y) print(args) foo(1,2,3,4,5) 输出结果: C:\Python35\python3.exe C:/Users/ZR/PycharmProjects/python全栈开发/day15/def函数.py 1 2 (3, 4, 5) def foo(x,y,*args): print(x,y) print(args) foo(1,2,*[3,4,5]) 输出结果: 1 2 (3, 4, 5) def foo(x,y,z): print(1,2,3) foo(*[1,2,3]) 输出结果: 1 2 3 # ############ **kwargs ################### def foo(x,y,**kwargs): print(x,y) print(kwargs) foo(1,y=2,a=1,b=2,c=3) 输出结果: 1 2 {'c': 3, 'a': 1, 'b': 2} def foo(x,y,**kwargs): print(x,y) print(kwargs) foo(1,y=2,**{'a':1,'b':2, 'c':3}) 输出结果: #更上面输出结果相同,只不过位置有所变化 1 2 {'a': 1, 'b': 2, 'c': 3} def foo(x,y,z): print(x, y, z) foo(**{'z':1,'x':2,'y':3}) 输出结果: 2 3 1 # ##### *args + **kwargs############ def foo(x,y): print(x,y) def wrapper(*args,**kwargs): print('==========>') foo(*args,**kwargs) #5、命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递 def foo(x,y,*args,a=1,b,**kwargs): print(x,y) print(args) print(a) print(b) print(kwargs) foo(1,2,3,4,5,b=3,c=4,d=5) 输出结果: 1 2 (3, 4, 5) 1 3 {'c': 4, 'd': 5}
为什么要用参数?举例说明
如果不定义参数,用函数的话:(每个有相同功能的都写个函数,说好的代码简化呢?)
def cpu报警邮件(): # 发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 def 硬盘报警邮件(): # 发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 def 内存报警邮件(): # 发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if CPU利用率 > 90%: cpu报警邮件() if 硬盘使用空间 > 90%: 硬盘报警邮件() if 内存占用 > 80%: 内存报警邮件()
使用函数:(代码明显少了很多,把重复内用改为参数调用!)
def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
函数的四种不同的参数:
1、普通参数
2、默认参数
3、动态参数
普通参数:
# #### 定义函数 ############### # name 叫做函数func的形式参数,简称:形参 def func(name): print(name) # #### 执行函数 ############### # 'zhurui' 叫做函数func的实际参数,简称:实参 func('zhurui')
但是普通参数有个问题!你在定义参数的时候定义了几个参数,你在调用的时候必须给他几个参数否则会报错!
def func(name,age): print(name,age) func('william') 报错提示: TypeError: func() missing 1 required positional argument: 'age' 其正确的写法是: def func(name,age): print(name,age) func('william',24) 输出结果: william 24
默认参数:
在你没有给他指定参数的时候它就会使用默认参数!
def func(name, age = 24): print('%s:%s' %(name,age)) # 指定参数: func('william', 32) 输出结果: william:24 # 使用默认参数 func('william') 输出结果: william:27
目录4
test....................4
目录5
test....................5