美文网首页
py_14 函数基本使用和参数

py_14 函数基本使用和参数

作者: 阿登20 | 来源:发表于2020-08-11 00:45 被阅读0次

    函数

    一、引入
    二、定义函数
        作用:提高编写效率,代码重复利用 代码简洁 方便修改,更易扩展 保持代码的一致性
        三种定义方式:
            1.无参函数 2. 有参函数 3. 空函数
    三、函数调用
        1. 语句的形式:只加括号调用
        2. 表达式:
        3. 函数调用可以当参数
    四、函数返回值
        1.  没有return或者return 或者return None ===> 返回None
        2. 返回一个值:return x
        3. 返回多个值,逗号分隔开,返回的是一个元组: return 1,3,5
    五、函数的参数
    python中所有值的传递,传递的都不是值的本身,而是值的引用,即内存地址
    形参:定义时的参数,也是局部变量
    实参:调用的传参值
    位置参数:一个萝卜一个坑,不能多不能少,位置一一对应
    默认参数:函数定义时,调用时能少写实参,放在位置参数后面
            定义默认参数时,必须是不可变类型
            可变类型的默认参数,在函数内部修改,默认参数也会修改
    关键字参数:
            函数调用,key=value不用按照顺序书写,放在位置参数后面
    可变参数:*args,**kwargs。分别是元组 和 字典
    命名关键字参数:没有可变参数时候,前面要用*占坑。
                传参时,书写要key=value的格式
    顺序书写:位置参数,默认参数,可变参数,命名关键字参数
        
    

    一、引入

    比如一个修理工会事先准备好螺丝刀、锤子等工具,这样在进行修理的过程中,需要用到拧螺丝的功能时就直接拿来螺丝刀使用,需要用到锤击物体的功能时就直接拿来锤子使用,而无需临时制造。这个例子的核心在于’事先准备好工具’,遇到应用场景时’拿来就用’,。

    在程序中,具备某一功能的‘工具’指的就是函数,‘事先准备工具’的过程即函数的定义,‘拿来就用’即函数的调用

    二、定义函数

    1.定义

    # 定义
    def 函数名(参数名1,参数名2):
        """文档字符串"""
        # 函数体
        return 表达式
    
    
    def add(x:int, y:int) -> int: # x,y为int型,函数返回为int型,只是注释,参数格式非法不会报错
        pass 
        return x+y
    
    1. def: 定义函数的关键字;

    2. 函数名:函数名指向函数内存地址,是对函数体代码的引用。函数的命名应该反映出函数的功能;

    3. 括号:括号内定义参数,参数是可有可无的,且无需指定参数的类型;

    4. 冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代码;

    5. """文档字符串""": 描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性;

    6. 函数体:由语句和表达式组成;

    7. return 值:定义函数的返回值,return是可有可无的。

    函数的作用

    .为什么使用函数:
    1.不适用函数: 组织结构不清晰,可毒性差
    2.代码冗余
    3.可维护性、扩展性差
    
    作用:
        提高编写效率,代码重复利用
        代码简洁
        方便修改,更易扩展
        保持代码的一致性
    

    2.三种定义方式:

    形式一:无参函数

    def func():
        print("无参数函数")
    # 调用
    func()
    
    # 定义函数发生的事情
    # 1. 将申请内存空间保存函数体代码
    # 2. 将上诉内存地址绑定给函数名
    # 3. 定义时不会执行函数体代码,但是检测代码语法。只有调用时才会执行函数代码
    
    # 调用函数发生的事情
    print(func) # <function func at 0x0000000002936488>
    # 1. 通过函数名找到函数的内存地址
    # 2. 然后加括号就是在触发函数体代码的执行
    func()
    
    # 示范1
    def bar(): # 函数定义会检测函数体代码语法
        print("i am adeng")
    def foo():  # 函数定义会检测函数体代码
        bar()
        print("阿登")
    foo() # 调用时才会执行函数代码
    
    # 示范2
    def foo():
        bar()
        print("阿登")
    
    def bar():
        print("i am adeng")
    foo()
    # 示范3
    def foo():
        bar()
        print("阿登")
    foo() # 会报错 调用时报错,因为函数体中的代码bar() 找不到这个函数
    def bar():
        print("i am adeng")
    

    形式2:有参函数

    # 形式2:有参函数
    # 如果把函数比喻成一个工厂,那么参数就是原材料,返回值是产品
    def func(x,y): # x,y 材料
        return x+y # 产品
    func(1,2) # 1传给x  2传给y,位置参数 一一对应
    print(func.__doc__)
    

    形式3:空函数

    # 形式三:空函数
    def func():
        pass # 占位符
    func()
    # 构思代码的时候使用 空函数
    

    三、函数调用

    1. 语句的形式:只加括号调用

    def foo():
        print("adneg")
    
    def add(x,y):
        return x+y
    
    foo()
    

    2. 表达式:

    # 赋值表达式
    res = add(1,2)
    print(res)
    # 数学表达式
    res = add(1,2)*10
    print(res)
    

    3.函数调用可以当参数

    res1= add(1,add(1,2))
    print(res1)
    

    四、函数返回值

    1. 没有return或者return 或者return None ===> 返回None

    2. 返回一个值:return x

    3. 返回多个值,逗号分隔开,返回的是一个元组: return 1,3,5

    # 函数体代码一旦运行到return会立刻终止函数的运行。
    def add(x,y):
        print('111')
        return x+y # return下面代码不会执行
        print("222")
    
    res = add(1,2)
    
    # 1 没有return或者return 或者return None ===> 返回None
    # 2 返回一个值:return x
    # 3.返回多个值,逗号分隔开,返回的是一个元组: return 1,3,5
    

    五、函数参数

    形参:定义时的参数,也是局部变量
    实参:调用的传参值
    位置参数:一个萝卜一个坑,不能多不能少,位置一一对应
    默认参数:函数定义时,调用时能少写实参,放在位置参数后面
            定义默认参数时,必须是不可变类型
            可变类型的默认参数,在函数内部修改,默认参数也会修改
    关键字参数:
            函数调用,key=value不用按照顺序书写,放在位置参数后面
    可变参数:*args,**kwargs。分别是元组 和 字典
    命名关键字参数:没有可变参数时候,前面要用*占坑。
                传参时,书写要key=value的格式
    顺序书写:位置参数,默认参数,可变参数,命名关键字参数
    
    
    image.png

    默认参数

    1.默认参数的值在函数定义阶段被赋值的,被赋值的是内存地址

    2.python中所有值的传递,传递的都不是值的本身,而是值的引用,即内存地址

    # python中所有值的传递,传递的都不是值的本身,而是值的引用,即内存地址
    m =2
    def dunc(x,y=m): # y=> 2的内存地址
        print(x,y)
    m =3
    func(1) # print(1,2) 不是print(1,3)
    

    2.虽然默认值可以被指定为任意类型,但是不推荐使用可变类型

    # 默认参数是可变类型
    # 默认参数必须在位置参数 右边
    def foo(n, arg=[]): arg=> []的内存地址
        arg.append(n)
        return arg
    print(foo(1)) #   [1]
    print(foo(2)) #   [1, 2]
    
    # 解决方案如下
    def foo(n, arg=None):
        if arg is None:
            arg = []
        arg.append(n)
        return arg
    print(foo(1))  #  [1]
    print(foo(2)) #   [2]
    

    3.函数定义时默认参数的位置必须放在位置参数后面

    可变参数:*args,**kwargs分别是元组 和 字典

    • 可变长度指的是在函数调用时,传入的值(实参)的个数不固定。
    • 实参是用来为形参赋值,所以对应着,针对溢出的实参必须有对应的形参来接收
    # *形参名:用来接收溢出的位置参数,溢出的位置实参会被*args接收,args是一个元组
    def func(x,y,*z):
        print(x,y,z)
    
    func(1,2,3,4,5) # 1 2 (3, 4, 5)
    l = 7,8
    func(1,2,*l) # 1 2 (7, 8)
    func(1,2,l) # 1 2 ((7, 8),)
    
    # 求一个序列的和
    def my_sum(*args):
        res = 0
        for i in args:
            res +=i
        return res
    res = my_sum(1,2,4,7)
    print(res) #  14
    
    # **形参名:用来接收溢出的关键字实参,**会将溢出的关键字实参保存成字典,赋值给紧跟其后的形参名**kwargs.kwargs是一个字典
    *args放在**kwargs前面
    
    def func(x,y,**kwargs):
        print(x,y,kwargs)
    
    func(1,y=2,a=3,b=4,c=5) # 1 2 {'a': 3, 'b': 4, 'c': 5}
    l = {"a":5,"b":8}
    func(1,2,**l) # 1 2 {'a': 5, 'b': 8}
    
    
    • 函数定义:*和**是打包成一个元组和字典
    • 函数调用:*和** 是解包。 * 可以看成对迭代对象的for循环得到的位置参数。**是解包成key=value.
    
    *和** 混用
    def index(x,y,z):
        print(x,y,z)
    # 函数定义*和**是打包:*是实参位置参数打包成元组,**是实参关键字参数key=value打包成字典
    def wrapper(*args,**kwargs):# args=(1,) kwargs ={"z":2,"y":3}
        index(*args,**kwargs) # index(1,z=2,y=3) # 函数调用*和** 是解包
      # index(*(1,),**{"z":2,"y":3})
      # index(1,x=2,y=3)
    
    wrapper(1,z=2,y=3)  # 1 3 2
    # 上面wrapper传参的格式,其实是受index函数的格式。
    

    命名关键字参数 *

    • 有可变参数 形参*args **kwargs时候 *可以胜率
    • 没有 *保留
    • 命名关键字实参 必须按照key=value的形式传参
    
    def func(a,b,*,c,d):
        print(a,b,c,d) # 1 2 3 4
    func(1,2,c=3,d=4)
    
    def bar(a,b,*args,c,d):
        print(a,b,c,d) # 1 2 3 4
    bar(1,2,5,6,7,c=3,d=4)
    
    def my(a,*,b=4,c): # 这里c不是位置参数,是命名关键字参数,放在了位置参数a后面没有报错
        print(a,b,c) # 1 4 22
    my(1,c=22)
    
    # 书写顺序 位置参数 默认参数 *args 命名关键字 **kwargs
    def bar(a,b,*args,c,d,**kwargs): # **kwargs 放在命名关键字c,d之前会报错
        print(a,b,c,d) # 1 2 3 4
    bar(1,2,5,6,7,c=3,d=4)
    

    定义函数形参书写顺序:位置参数 默认参数 *args 命名关键字 **kwargs

    相关文章

      网友评论

          本文标题:py_14 函数基本使用和参数

          本文链接:https://www.haomeiwen.com/subject/avzsdktx.html