python(四)函数
一、背景
在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
while True : if cpu利用率 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 > 80 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 |
上面代码可以看出,整个发邮件的代码都是重复的,可以优化成以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True : if cpu利用率 > 90 % : 发送邮件( 'CPU报警' ) if 硬盘使用空间 > 90 % : 发送邮件( '硬盘报警' ) if 内存占用 > 80 % : |
优化后的代码无论是从可读性还是重用性上都要比之前的代码要好,这就是函数式编程和面相过程变成的区别:
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
面相对象:对函数进行分类和封装,让开发“更快更好更强”
函数式编程最重要的是增强代码的重用性和可读性。
二、函数的定义和使用
1
2
3
4
5
|
def 函数名(参数): 函数体 返回值 |
函数的定义主要有如下五点:
def:函数的关键字,python解释器读到这里,知道是要定义函数了
函数名:函数的名称,日后通过函数名来调用函数
函数体:函数中进行一系列的逻辑计算,
参数:为函数体提供数据
返回值:当函数执行完毕后,可以给调用者返回数据。让调用者知道,函数是否执行成功。
1、返回值
返回值用来告知调用者函数是否执行成功
1
2
3
4
5
6
7
8
9
10
11
|
def f1(): print ( 123 ) # 在函数中,一旦执行return,函数执行过程立即终止 return "111" print ( 456 ) r = f1() print (r) 执行结果: 123 111 |
从上面的结果可以看出,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。
2、参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
def CPU报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 def 硬盘报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 def 内存报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True : if cpu利用率 > 90 % : CPU报警邮件() if 硬盘使用空间 > 90 % : 硬盘报警邮件() if 内存占用 > 80 % : 内存报警邮件() |
以上例子可以看出,如果没有参数,无法自定义邮件内容,不灵活。带参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def 发送邮件(邮件内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True : if cpu利用率 > 90 % : 发送邮件( "CPU报警了。" ) if 硬盘使用空间 > 90 % : 发送邮件( "硬盘报警了。" ) if 内存占用 > 80 % : 发送邮件( "内存报警了。" ) 这样可以清晰看出来邮件报警,哪里出了问题。 |
a.普通参数(严格按照顺序,将实际参数赋值给形式参数)
1
2
3
4
5
6
|
def f1(name): #name叫做函数的形式参数,简称形参 print (name) f1( 'yangyang' ) #yangyang叫做函数f1的实际参数,简称实参 执行结果: yangyang |
b.指定参数
1
2
3
|
def f1(name,age,sex): print (name,age,sex) f1(age = 22 ,name = 'yangrz' ,sex = 'man' ) |
c.默认参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def send(yy, content, xx = "OK" ): #定义函数时,xx="OK" 这种写法为默认参数,如果调用函数时不指定,则默认输出此值(OK)。 #默认参数必须放置在参数列表的最后 print (yy, content, xx) print ( "发送邮件成功:" , xxoo, content) return True while True : em = input ( "请输入邮箱地址:" ) result = send(em, "didi" , "ok" ) #em、didi、ok分别对应定义函数时,send()中的yy,content,xx。如果不写ok,name输出xx时,默认为OK。 if result = = True : print ( "发送成功" ) else : print ( "发送失败" ) |
默认参数必须放置在参数列表的最后,如果调用函数时不指定,则默认输出定义函数时定义的值。
d.动态参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
* 默认将传入的参数,全部放置在元组中, f1( * [ 11 , 22 , 33 , 44 ]) def f1( * args): # args = (11,) args = ([ 11 , 22 , "alex" , "hhhh" ], "12" ) print (args, type (args)) f1() 执行结果: ([ 11 , 22 , 'alex' , 'hhhh' ], '12' ) < class 'tuple' > 由执行结果可以看出, * args 参数会把所有的值放置到元组中。 def f1( * args): print (args) f1( 11 , 22 , 33 , 44 ) #执行结果: ( 11 , 22 , 33 , 44 ) #把传入的参数放置到元组中 li = [ 11 , 22 , 33 , 44 ,] f1( * li) #通过*列表名的方式将列表传入到函数中,把列表中的每一个值添加到元组中 执行结果: ( 11 , 22 , 33 , 44 ) f1(li) #不加*,将整个列表作为一个元素添加到元组 执行结果: ([ 11 , 22 , 33 , 44 ],) * * 默认将传入的参数,全部放置在字典中 f1( * * { "kl" : "v1" , "k2" : "v2" }) def f1( * * args): print (args) #执行方式一 f1(n1 = "biubiubiu" , n2 = 18 , "name" = "yangrz" ) 执行结果:{ 'n1' : 'biubiubiu' , #执行方式二,定义字典,结果kk:{字典} dic = { 'k1' : "v1" , "k2" : "v2" } f1(kk = dic) 执行结果:{ 'kk' : { 'k2' : 'v2' , 'k1' : 'v1' }} dic = { 'k1' : "v1" , "k2" : "v2" } #把字典的元素传入到函数中 f1( * * dic) 执行结果:{ 'k2' : 'v2' , 'k1' : 'v1' } |
e.万能参数 (*args,**kwargs)
1
2
3
4
5
6
7
8
9
10
11
|
def f1( * args, * * kwargs): #传入的是数字、字符串、列表就传入*args,如果是字典就传入**kwargs print (args) print (kwargs) f1( 11 , 22 , 33 ) # 执行结果: # (11, 22, 33) # {} f1(k1 = "v1" ) 执行结果:{ 'k1' : 'v1' } |
利用动态参数实现format功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# format的方法如下: def format ( * args, * * kwargs): #万能参数,故可以使用以下三种方式实现format功能 s1 = "My name is {0} age {1}" . format ( "yangrz" , 18 ) #*args接收字符串 print (s1) # 执行结果:My name is yangrz age 18 s2 = "My name is {0} age {1}" . format ( * [ "yangrz" , 18 ]) #*args接收*列表的方式,把列表中的值传入 print (s2) # 执行结果:My name is yangrz age 18 s3 = "My name is {name} age {age}" . format ( * * { "name" : "yangrz" , "age" : 19 }) #**kwargs通过**字典的方式,将字典中的key-values传入 print (s3) #执行结果:My name is yangrz age 19 |
函数中的异常处理(try语句)
1
2
3
4
5
6
7
8
9
10
11
|
def func(): try : print ( 123 ) except : print ( "执行失败" ) else : print ( "执行成功" ) func() # 执行结果: # 123 # 执行成功 |
该种异常处理语法的规则是:
· 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
· 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
· 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
· 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
· 如果没有发生异常,则执行else块代码。
三、函数内容补充
1
2
3
4
5
6
|
def f1(a1): a1.append( 999 ) li = [ 11 , 22 , 33 ] f1(li) print (li) 执行结果:[ 11 , 22 , 33 , 999 ] |
说明:函数传入参数的时候,传入的是引用。列表li传入a1后,a1引用的内存中li开辟的列表空间,因此当a1.append(999)时,列表li的值也是会变的。
1
2
3
4
5
6
7
8
|
def f1(a1, a2): print (a1 + a2) def f1(a1, a2): print (a1 * a2) f1( 8 , 8 ) #执行结果:64 |
在python解释器中,上段代码的执行顺序:
1、定义函数f1,指向内存中的一块儿空间(print(a1 + a2))
2、定义函数f1,指向内存中的另一块儿空间(print(a1 * a2))
3、执行f1(8,8)
因为此时函数f1指向的是后来定义的(print(a1 * a2)) ,故结果为64.
函数的全局变量:
局部变量:自己创建自己用
全局变量:所有的作用域里都能读
对全局变量进行【重新赋值】,需要global
特殊的:列表字典,可修改,不可重新赋值
1
2
3
4
5
6
7
|
name = "yangrz" def f1(): age = 18 name = "123" print (age,name) f1() #执行结果:18 123 |
如果函数中调用的变量在函数中存在、全局中也存在,优先使用自己定义的变量,如果自己没有定义这个变量,再去父类去找,父类没有,再向上一层一层去找。
1
2
3
4
|
def f1(): age = 18 print(age) #这样执行会报错 |
函数中的变量,外部无法使用。只能自己使用。
global可以在函数中对全局变量重新赋值:
1
2
3
4
5
6
7
|
age = 10 def f1(): global age age = 18 f1() print (age) |
全局变量的命名规则:
全部都是大写,如:NAME = 'yangrz' AGE = 19,这样在引用的时候,就知道它是全局变量。
四、内置函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
n = abs ( - 1 ) #abs()求绝对值 print (n) # 执行结果 1 #0,None,"",[],(),{} 这些值的结果都是False n = all ([ 1 , 2 , 3 , None ]) #all()里边是一个可迭代东西,只要里边有一个为False,结果就是False print (n) #执行结果:False n = any ([ 1 , 0 ,(), None ]) #与all相反,只要里边有一个为True,结果就为True print (n) #执行结果:True ascii() #自动执行对象的__repr__方法 # bin() # oct() # hex() #以上三个函数,分别是输出一个10进制数字的2进制、8进制、16进制的表示 print ( bin ( 10 )) print ( oct ( 10 )) print ( hex ( 10 )) #执行结果: 0b1010 0o12 0xa #utf-8 一个汉字占3个字节 #gbk 一个汉字占2个字节 # bytes() s = "李杰" #一个字节8位,一个汉字三个字节 #01010101 10101010 10101011 01010101 10101010 10101011 # 23 23 23 23 23 23 # 2f 2f 2f 2f 2f 2f #bytes() 把字符串转换成字节类型 #用法:bytes(要转换的字符串, 按照什么编码) print (bytes(s,encoding = "utf-8" )) #执行结果:b'\xe6\x9d\x8e\xe6\x9d\xb0' print (bytes(s,encoding = "gbk" )) #执行结果:b'\xc0\xee\xbd\xdc' #str(字节,encoding="utf-8") 把字节转换成字符串 print ( str (bytes(s,encoding = "utf-8" ),encoding = "utf-8" )) #执行结果:李杰
|
python(四)函数的更多相关文章
- Python 全栈开发四 python基础 函数
一.函数的基本语法和特性 函数的定义 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的.函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数 ...
- python学习笔记(四):函数
一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pasc ...
- Python中函数传递参数有四种形式
Python中函数传递参数有四种形式 fun1(a,b,c) fun2(a=1,b=2,c=3) fun3(*args) fun4(**kargs) 四种中最常见是前两种,基本上一般点的教程都会涉及, ...
- Python虚拟机函数机制之位置参数(四)
位置参数的传递 前面我们已经分析了无参函数的调用过程,我们来看看Python是如何来实现带参函数的调用的.其实,基本的调用流程与无参函数一样,而不同的是,在调用带参函数时,Python虚拟机必须传递参 ...
- Python之函数与变量
本节内容 函数介绍及其作用 函数的定义与调用 函数的参数说明 全局变量与局部变量 值传递和引用传递 一.函数的介绍及其作用 编程语言中的函数与数学中的函数是有区别的:数学中的函数有参数(输入),就会有 ...
- Python之函数进阶
本节内容 上一篇中介绍了Python中函数的定义.函数的调用.函数的参数以及变量的作用域等内容,现在来说下函数的一些高级特性: 递归函数 嵌套函数与闭包 匿名函数 高阶函数 内置函数 总结 一.递归函 ...
- python 中函数的参数
一.python中的函数参数形式 python中函数一般有四种表现形式: 1.def function(arg1, arg2, arg3...) 这种是python中最常见的一中函数参数定义形式,函数 ...
- python 中函数参数传递形式
python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...
- 第三章:Python基础の函数和文件操作实战
本課主題 Set 集合和操作实战 函数介紹和操作实战 参数的深入介绍和操作实战 format 函数操作实战 lambda 表达式介绍 文件操作函数介紹和操作实战 本周作业 Set 集合和操作实战 Se ...
随机推荐
- Mysql 性能调优之Memory 计算
最近在做mariadb 数据库性能调优时发现,配置文件影响着整个数据库的性能的百分之80(这么说不为过),现在就我出现的问题来分析. 在压测mariadb时,tail 日志.发现压测到一半 ,数据库会 ...
- classmethod一个用处是创建可选类构造器
Definition and Introduction通常来说, descriptor 是一种绑定着特殊行为属性的对象, 在访问它时行为被descriptor协议定义的方法所重载.这些方法是__get ...
- 【转】Spring 获取web根目录 (Spring线程获取web目录/路径/根目录,普通类获取web目录)
不使用Spring,怎样能在Listener启动的Thread中获取web目录,还真不完全确定.其实我觉得实际代码也很简单.就是基于普通的listener,然后在listener中获取web目录并放到 ...
- 【iCore3 双核心板】例程十六:USB_HID实验——双向数据传输
实验指导书及代码包下载: http://pan.baidu.com/s/1bojcVoV iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- hibernate学习(3)——api详解对象(2)
1. Transaction 事务 事务的操作: 开启事务 beginTransaction() 获得事务 getTransaction() 提交事务:commit() 回滚事务:rollback ...
- 追踪app崩溃率、事件响应链、Run Loop、线程和进程、数据表的优化、动画库、Restful架构、SDWebImage的原理
1.如何追踪app崩溃率,如何解决线上闪退 当 iOS设备上的App应用闪退时,操作系统会生成一个crash日志,保存在设备上.crash日志上有很多有用的信息,比如每个正在执行线程的完整堆栈 跟踪信 ...
- 整理常用的iOS第三方资源
一:第三方插件 1:基于响应式编程思想的oc 地址:https://github.com/ReactiveCocoa/ReactiveCocoa 2:hud提示框 地址:https://github. ...
- 循环调用MAIN
--单位转移录入declare oi_errcode integer; oc_errtext varchar2(100);begin for p in (select * from ssunitinf ...
- Force StyleCop to Ignore a File
You can quickly force StyleCop to ignore files in a project by manually modifying the project file, ...
- RDIFramework.NET V2.9版本 WinFom部分新增与修正的功能
RDIFramework.NET V2.9版本 WinFom部分新增与修正的功能 转眼间RDIFramework.NET框架走了快6个年头了,随着一个版本一个版本的升级改造,现在已经越来越完美了.使 ...