标签:
在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:
|
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
2
3
4
5
6
7
8
9
10
11
|
def f1(): print(123) # 在函数中,一旦执行return,函数执行过程立即终止 return "111" print(456)r = f1()print(r)执行结果:123111 |
从上面的结果可以看出,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。
|
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%: 发送邮件("内存报警了。")这样可以清晰看出来邮件报警,哪里出了问题。 |
|
1
2
3
4
5
6
|
def f1(name): #name叫做函数的形式参数,简称形参 print(name)f1(‘yangyang‘) #yangyang叫做函数f1的实际参数,简称实参执行结果:yangyang |
|
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 Truewhile 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("发送失败") |
默认参数必须放置在参数列表的最后,如果调用函数时不指定,则默认输出定义函数时定义的值。
|
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‘} |
|
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‘} |
|
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 18s2 = "My name is {0} age {1}".format(*["yangrz",18])#*args接收*列表的方式,把列表中的值传入print(s2)# 执行结果:My name is yangrz age 18s3 = "My name is {name} age {age}".format(**{"name":"yangrz","age":19})#**kwargs通过**字典的方式,将字典中的key-values传入print(s3)#执行结果:My name is yangrz age 19 |
|
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 = 18print(age)#这样执行会报错 |
函数中的变量,外部无法使用。只能自己使用。
global可以在函数中对全局变量重新赋值:
|
1
2
3
4
5
6
7
|
age = 10def f1(): global age age = 18f1()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,"",[],(),{} 这些值的结果都是Falsen = all([1,2,3,None])#all()里边是一个可迭代东西,只要里边有一个为False,结果就是Falseprint(n)#执行结果:Falsen = any([1,0,(),None])#与all相反,只要里边有一个为True,结果就为Trueprint(n)#执行结果:Trueascii()#自动执行对象的__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"))#执行结果:李杰
|
标签:
原文地址:http://www.cnblogs.com/yangruizeng/p/5536508.html