zoukankan      html  css  js  c++  java
  • 八. Python基础(8)--函数

    八. Python基础(8)--函数

    1 ● 函数返回布尔值

    注意, 自定义的函数也可以是用来作逻辑判断的, 例如内置的startswith()等函数.

    def check_len(x):

        '''

     

        :param x:

        :return:

        '''

        if len(x) > 5:

            return True

        # 如果这里不写else, 并return一个False, 那么返回一个None, 相当于False.

     

    2 ● 为函数添加说明文档

    print(check_len.__doc__)

    '''

    结果:

        :param x: *******

        :return: *******

    '''

     

    3 ● 有关函数的执行步骤

    程序从上到下执行到一个函数定义的语句时, 内存中只是保存了函数名, 并没有执行函数体内的语句

     

    3 ● 函数的作用

    ① 减少代码的冗余

    ② 提高代码的可读性

    ③ 提高代码的重用性

    ④ 提高代码的的可扩展性

    ⑤ 解耦

     

    4 ● 解耦(decoupling)

    面向过程的编程--功能与功能之间耦合很紧密

    解耦--把一个功能尽量细化成多个小功能, 并且功能与功能之间的影响尽量减到最小--不宜把一个很复杂的功能放在一个函数里

    程序要做到: "高内聚, 低耦合"high cohesion and low coupling

     

    5 ● Python3允许使用汉语作为函数名

    def 函数名(参数1, 参数2): # 形参

        '''

        这是一个解决什么问题的函数

        :param 参数1:

        :param 参数2:

        :return:

        '''

        print('函数体')

        返回值 = [参数1, 参数2]

        return 返回值

     

    接受返回值 = 函数名('刘桂香', 88) # 实参

    print(接受返回值)

    函数体

    ['刘桂香', 88]

     

    6 ● 默认参数

    可以不给它传值的形参

    如果不给它传值, 那么实参接收默认值,如果给它传了值, 就接收传入的值

    默认的值是在定义阶段就已经确定了

    a = 18

    def age(a1, a2 = a):

        print(a1, a2)

    a = 20

     

    age(10) # 10 18

     

    7 ● 默认参数的陷阱: 针对可变的数据类型

    def demo3(a = []):

        a.append(1)

        print(a)

    #

    # demo3()

    # demo3() # 仍用默认的列表

    # demo3() # 仍用默认的列表

    # '''

    # [1]

    # [1, 1]

    # [1, 1, 1]

     

    # '''

    # demo3([]) # 用新列表

    # demo3([]) # 用新列表

    # demo3([]) # 用新列表

    '''

    [1]

    [1]

    [1]

    '''

     

    # demo3()

    # demo3([]) # 用新列表, 而不是默认的列表

    # demo3() # 用默认的列表

    '''

    [1]

    [1]

    [1, 1]

    '''

    # 还有一种解决方法是在进入函数体的时候置空默认的列表

    def demo3(a = []):

        a = []

        a.append(1)

        print(a)

    #

    # demo3()

    # demo3() # 仍用默认的列表

    # demo3() # 仍用默认的列表

    '''

    [1]

    [1]

    [1]

    '''

     

    8 ● 动态参数(dynamic argument)/变长参数(variable length argument)

    We can collect the arguments using the * and ** specifiers in the function's parameter list; this gives you the (unnamed) positional arguments as a tuple and the (named) keyword arguments as a dictionary.

    在形式参数前面添加标识符"*", 表示我们可以将任意数量的、无名的(unnamed)位置实参以元组的形式传递给形参.

    在形式参数前面添加标识符"**", 表示我么可以将任意数量的、有名的(named)关键字实参以字典的形式传递给形参.

     

    9 ● 动态参数*args

    #① 站在函数定义的角度: *做组合(gather), 将多个参数组合成一个元组

    #② 站在函数调用的角度: *做打撒(unpack)(打散列表, 元组, 字符串), 将一个列表或者元组打散成多个参数

    # * 只针对按位置传参

    def my_sum(*args): # 实参会组合成一个元组

        count_sum = 0

        for i in args:

            count_sum += i

        return count_sum

     

    print(my_sum(1,2,3)) # 1,2,3 组合成一个元组, 结果: 6

    li = [1,2,3]

    print(my_sum(*li)) # 先将列表li打散成1,2,3, 再将1,2,3组合成后元组, 结果: 6

     

    10 ● 动态参数**kwargs

    #① 站在函数定义的角度: *做组合(gather)

    #② 站在函数调用的角度: *做打撒(unpack)(打散列表或者元组)

    # ** 只针对按关键字传参

    def demo4(**kwargs):

        print(kwargs)

     

    demo4(a = 1, b = 2, c = 3) # 关键字a,b,c不用加引号, 结果的键有引号: {'a': 1, 'b': 2, 'c': 3}

    dic = {'a': 1, 'b': 2, 'c': 3}

    demo4(**dic) # 先将词典dic打散, 然后组合为一个词典,结果和dic一模一样: {'a': 1, 'b': 2, 'c': 3}

     

    11 ● 动态函数*args和**kwargs的混用

    def demo5(*args, **kwargs):

        print(args)

        prind = {'a':11, 'b':22, 'c':33}

     

    t = (1,2,3)

    d = {'a':11, 'b':22, 'c':33}

     

    print(*t) # 1 2 3

    demo5(*t)

    '''

    (1, 2, 3)

    {}

    '''

    print(*d) # a b c, 不能用**d

    demo5(**d)

    '''

    ()

    {'a': 11, 'b': 22, 'c': 33}

    '''

     

    12 ● 参数划分的总结:

    # 站在传参(实参给形参传递参数)的角度or站在函数调用的角度: 所有的参数都是实际参数

    ①按位置传值

    ②按关键字传值

     

    # 站在形参接受实参传递的值的角度or站在函数定义的角度:所有的参数都是形式参数

    ①位置参数

    ②默认参数

    ③动态参数: *args, ** kwargs

    ※定义顺序:位置参数, 动态参数 * args, 默认参数, 动态参数 ** kwargs

     

    13 ● 作为形参的位置参数, 动态参数*args, 默认参数, 动态参数**kwargs的定义顺序

    def func(位置参数1, 位置参数2, *args, 默认参数 = 10, **kwargs):

        print(位置参数1, 位置参数2)

        print(默认参数)

        print(args)

        print(kwargs)

     

    # func(1,2,3,4,5,默认参数= 'hahaha', a =10, b =20)

    '''

    1 2

    hahaha

    (3, 4, 5)

    {'a': 10, 'b': 20}

    '''

    # func(1,2,3,4,5,a=10, b=20)

    '''

    1 2

    10

    (3, 4, 5)

    {'a': 10, 'b': 20}

    '''

     

    14 ● 区分关键字参数和默认参数

    关键字参数是针对实参而言的, 准确来说, 它是按照关键字传值的实参

    默认函数是针对形参而言的

    # 有关键字参数

    def foo(bar, baz):

        pass

     

    foo(1, 2) # 按照位置(position)传值的实参

    foo(baz=2, bar=1) # 按照关键字(keyword)传值的实参

    # 有关默认参数

    def foo(baz, bar =5): # 默认形参前可以有位置形参

        print(baz, bar)

     

    foo(1, 2) # 1 2

    foo(1) # 1 5

     

     

    # 下面的代码报错(non-default argument follows default argument)

    def foo(bar =5, baz): # 默认参数后不允许有位置参数

        print(baz, bar)

     

    foo(1, 2)

    # 详见下面代码, 注意区分关键字参数和默认参数

    def fun1(x=5, **kwargs):

        print(x)

        print(kwargs)

     

    # fun1(a=1, b=2)

    '''

    5

    {'a': 1, 'b': 2}

     

    fun1(a=1, b=2)

    '''

     

    # fun1(x=7, a=1, b=2)

    '''

    7

    {'a': 1, 'b': 2}

    '''

    # fun1(7, a=1, b=2)

    '''

    7

    {'a': 1, 'b': 2}

    '''

     

    # fun1(7, x=1, b=2)

    '''

    fun1() got multiple values for argument 'x'

    '''

     

    # ⑤

    '''

    def fun1(x=5, *args):

        print(x)

        print(args)

     

    fun1(1,3,6)

    '''

     

    # 注意: 这里虽然没有报错, 但是作为默认参数的x就没有意义了, 因为此时没有办法在不给x传值的情况下还能打印出默认的5

     

    # ⑥

    '''

    def fun1(*args, x=5):

        print(x)

        print(args)

     

    fun1(1,3,6)

    '''

    # 注意: 这里的x不是关键字参数, 而是默认参数

    '''

    5

    (1, 3, 6)

    '''

     

    15 ● 函数的嵌套

    def func():

        print(123)

        def func2():

            print(345)

     

        if __name__ == '__main__':

            func2() # 如果注释掉此行, 那么func2不会运行

     

    func()

     

    16 ● 函数嵌套的应用场景

    # 例如: 生成验证码

    # 画线

    # 打点

    # 生成图片

     

    def 生成验证码():

        def 画线():

            pass

        def 打点():

            pass

        def 生成图片():

            pass

        画线()

        打点()

        生成图片()

    函数嵌套使用的目的: 为了保证某些功能特有的函数不被其他人随意地调用

     

    17 ● 如何给内嵌的函数传实参?

    # 方法1:

    def func(x, y, z):

        print(x, y, z)

        def func_inner(a,b,c):

            print('func_inner', a, b, c)

        func_inner(x, y, z)

     

    func(4,5,6)

    '''

    4 5 6

    func_inner 4 5 6

    '''

    # 方法2(升级版, 使用动态参数)

    def func(*args, **kwargs):

        print(args)

        print(kwargs)

        def func_inner(a,b,c):

            print('func_inner', a,b,c)

        func_inner(*args, **kwargs)

     

    func(1,2, 3)

    '''

    (1, 2, 3)

    {}

    func_inner 1 2 3

    '''

    func(1, b = 2, c = 3)

    '''

    (1,)

    {'b': 2, 'c': 3}

    func_inner 1 2 3

    '''

     

    知识补充:

    1● 有关函数的return

    def fun():

        return 123 # Python中, 一遇到return就会停止操作, 不会再执行

        return 456 # 不会被执行

     

    def fun():

        return (123, 456) # 返回一个元组, 可以返回其它任何数据类型

    # python返回值的种类:

    # ① 返回None--a, 如果函数里什么都不写; b, return; c,return None

    # ② 返回一个值,

    # ③ 多返回值, 以元组的形式

    return 111, {123, 456}

    # 返回一个元组(111, {123, 456})

    # 相当于: return(111, {123, 456})

    # return的作用;

    # ① 返回值

    # ② 结束函数

     

    2 ● 接收返回值

    # ① 一个对象接受一个值

    # ② 多个对象接受多个值, 个数要相等(拆包/解包(pack)的问题)

     

    3 ● 实参 & 形参

    # 站在函数定义的角度上, 所有的参数都叫形式参数, 简称形参

    # 站在函数调用的角度上, 所有的参数都叫实际参数, 简称实参

    The names given in the function definition are called parameters whereas the values you supply in the function call are called arguments.

    在函数定义时赋予的名称(names)叫作形参, 在函数调用时提供的值(values)叫作实参

    # Parameter: Functions are declared with 0 or more "formal parameters", which are unbound local variables. When the function is called, the argument

    # Argument: An expression passed to a function when it is called.

    函数的本质: an object resulting from evaluation of a def block or a lambda expression.

  • 相关阅读:
    [iOS基础控件
    [iOS基础控件
    后端程序员必会常用Linux命令总结
    MySQL数据库SQL语句基本操作
    MySQL拓展操作
    http/1.0/1.1/2.0与https的比较
    http中的socket是怎么一回事
    Django content_type 简介及其应用
    WEB主流框架技术(汇聚页)
    WEB基础技术(汇聚页)
  • 原文地址:https://www.cnblogs.com/ArrozZhu/p/8393629.html
Copyright © 2011-2022 走看看