python(四)函数

摘要:
Ifsresult==True:printelse:print默认参数必须放在参数列表的末尾。如果在调用函数时未指定,则默认输出定义函数时定义的值。
一、背景

在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:

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 函数名(参数):
 
    函数体
 
    返回值

函数的定义主要有如下五点:

  1. def:函数的关键字,python解释器读到这里,知道是要定义函数了

  2. 函数名:函数的名称,日后通过函数名来调用函数

  3. 函数体:函数中进行一系列的逻辑计算,

  4. 参数:为函数体提供数据

  5. 返回值:当函数执行完毕后,可以给调用者返回数据。让调用者知道,函数是否执行成功。

1、返回值

返回值用来告知调用者函数是否执行成功

1
2
3
4
5
6
7
8
9
10
11
def f1():
    print(123)
    # 在函数中,一旦执行return,函数执行过程立即终止
    return "111"
    print(456)
 
= 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()
执行结果:
([1122'alex''hhhh'], '12') <class 'tuple'>
由执行结果可以看出,*args 参数会把所有的值放置到元组中。
def f1(*args):
    print(args)
f1(11,22,33,44)
#执行结果:
(11223344)
#把传入的参数放置到元组中
li = [11,22,33,44,]
f1(*li)
#通过*列表名的方式将列表传入到函数中,把列表中的每一个值添加到元组中
执行结果:
(11223344)
f1(li)
#不加*,将整个列表作为一个元素添加到元组
执行结果:
([11223344],)
**     默认将传入的参数,全部放置在字典中   f1(**{"kl":"v1""k2":"v2"})
def f1(**args):
    print(args)
#执行方式一
f1(n1="biubiubiu", n2=18,"name"="yangrz")
执行结果:{'n1''biubiubiu',n2:18,"name":"yangrz"}
#执行方式二,定义字典,结果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)
执行结果:[112233999]

说明:函数传入参数的时候,传入的是引用。列表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,这样在引用的时候,就知道它是全局变量。

四、内置函数

python(四)函数第1张 

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
= abs(-1)
#abs()求绝对值
print(n)
# 执行结果  1
 
#0,None,"",[],(),{}   这些值的结果都是False
= all([1,2,3,None])
#all()里边是一个可迭代东西,只要里边有一个为False,结果就是False
print(n)
#执行结果:False
= 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()
= "李杰" #一个字节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'xe6x9dx8exe6x9dxb0'
print(bytes(s,encoding="gbk"))
#执行结果:b'xc0xeexbdxdc'
 
#str(字节,encoding="utf-8")   把字节转换成字符串
print(str(bytes(s,encoding="utf-8"),encoding="utf-8"))
#执行结果:李杰

 

免责声明:文章转载自《python(四)函数》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇员工想变股东需具备以下条件C#中使用7Z进行压缩解压下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python 函数参数使用

默认参数 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while True: ok = raw_input(prompt) if ok in ('y', 'ye', 'yes'): return True...

python ddt数据驱动二(json, yaml 驱动)

一、通过json文件驱动 import unittestfrom ddt import ddt, file_data@ddtclass MyTest(unittest.TestCase): # test_data_list.json里的数据是[1,2,3] @file_data('test_data_list.json') def tes...

python 安装PyV8 和 lxml

近来在玩python爬虫,需要使用PyV8模块和lxml模块。但是执行pip install xx 或者easy_install xx 指令都会提示一些错误。这些错误有些是提示pip版本过低或者缺少vc++ 9.0环境,再或者一些头文件无法引用等等。我也懒得找错误解决方法。就直接下载Pyv8模块的安装包和lxml的安装包。 Pyv8的安装包链接: 1.针对...

python合并表

1 import xlrd, xlwt 2 3 # 读取 4 rbook = xlrd.open_workbook('提取+病例合并.xlsx') # 打开文件 5 print("表1:") 6 sheet = rbook.sheet_by_index(0) # 打开对应的表 7 nrow = sheet.nrows...

Python -扩展C++-Pytorch扩展

1.Python whl 文件和 egg 文件 可以执行和效率是两码事 setup.py用来编译和安装扩展模块。负责编译c++模块,封装成python可以调用的形式 所有能被整合或导入到其它python脚本的代码,都可以被称为扩展 Python调用C库比较简单,不经过任何封装打包成so,直接使用python的ctypes调用即可。 Pytho...

Django项目中关于redis包版本的坑

1.环境 python:3.6 django:1.11.8 redis:3.2.1 2.遇到的问题 报错:redis.exceptions.DataError: Invalid input of type: 'UserInfo'. Convert to a byte, string or number first. 3.原因 不指定安装版本时,pip i...