zoukankan      html  css  js  c++  java
  • 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 函数名(参数):
     
        函数体
     
        返回值

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

    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,这样在引用的时候,就知道它是全局变量。

    四、内置函数

     

    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"))
    #执行结果:李杰

     

  • 相关阅读:
    centos7上安装memcached以及PHP安装memcached扩展(二)
    centos7上安装memcached以及PHP安装memcached扩展(一)
    centos7上安装redis以及PHP安装redis扩展(二)
    centos7上安装redis以及PHP安装redis扩展(一)
    Redis Desktop Manager无法连接虚拟机中启动的redis服务问题排查步骤
    CentOS 7设置开机启动服务,添加自定义系统服务
    delphi 选择文件夹目录保存
    mysql drop database ERROR 2013
    delphi 在别的方法 调用keypress事件
    delphi Inc Dec用法
  • 原文地址:https://www.cnblogs.com/yangruizeng/p/5536508.html
Copyright © 2011-2022 走看看