zoukankan      html  css  js  c++  java
  • 初见函数-函数的参数类型

    一、函数的介绍

      当我们写一个程序,如果相同的功能需要重复100次。

      在没有函数的情况下,我们需要复制粘贴100次。整个脚本文件就变得非常庞大。

      如果需要修改这个功能,那我们也需要修改100次。而且容易出错。 so  我们引进了函数。

        

    1.1 定义函数

      一个函数最基本的组成部分: 

          关键字   def

          函数名  函数名要反应其意义,就是命名规范

          注释   代码规范,解释该函数的作用,以及参数的作用

          函数体  这个函数需要完成的逻辑功能。

          返回值  默认为None,可以不写。但是我们都会定义自己的返回值。注意:函数一遇到return 就会结束了,后面的代码就不会执行了(if  else 嵌套return)。

    def 函数名(参数1,参数2,参数3,...):                   #函数名要能反映其意义
        '''注释'''
        函数体
        return 返回的值                   #

    1.2  函数的运行过程与调用

    1.2.1 调用

      函数名本质上就是函数的内存地址的标签

      调用: 函数名()         

        第一步: 先找到函数名 

        第二步: 根据找到的函数名,运行其中保存的代码

    函数名其实就是一个变量,其中保存了 函数的代码。  加上一个() 就运行了其中保存的代码了。

    1.2.2 运行过程  

    1 x = 100
    2 def add(a, b):
    3     y = a + b
    4     return y
    5 su = add(x, 100)

      第一步: 把 x = 100 加载到内存中。

      第二步: 把函数名add 与其 对应的函数体代码  放在内存中。 注:其下的代码在这时候,是没有运行的,只是保存到变量中。

      第三步:直接到第5行。 在内存中,找到上一步,add函数名变量。遇到(),执行该函数变量的保存的代码。这一步涉及到传递参数的内容,在下面会讲解。

      第四步:遇到return,返回到第5行,给su 赋值。

    1.3 函数的注释规范

    def odd(a: int, b: '默认值'=3 ) -> '写返回值':
        "函数说明,介绍函数的功能,会添加到__doc__中,可使用三引号多行,en首单词首字母大些"
        return a + b
    
    print(odd(3))

    二、参数传递

     1 x = 10000
     2 
     3 def add(a, b):  # 实参 到 形参的传递,其实就是指向了同一块内存,有两个别名而已
     4     print('Before', id(a))
     5     a += 1  # a = a + 1  ,前面的a是局部变量a(执行这句生成),新的一块内存,  后面的a是全局的
     6     print('after', id(a))
     7 
     8 print('globle before', id(x))
     9 add(x, 2)
    10 print('globle after', id(x))

    三、 参数类型

      函数中参数可以分为  位置参数 、 默认参数 、不定长参数

      参数排序的规则: 位置参数-->*args-->默认参数-->**kwargs  否则,解释器进行语法分析的时候 直接报错。   

    3.1 位置参数-必须传递参数

    def mymax(x, y):
        the_max = x if x > y else y
        return the_max
    
    maxnum = mymax()  # 此处不传参数
    print(maxnum)
    
    计算结果报错:
        maxnum = mymax()
    TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'

    3.2 默认参数

      可以不传递参数,但是默认参数,只会计算一次(在第一次调用的时候,进行赋值),如果进行了赋值,则指向一块新的内存地址。

    如下:

    def func(a, b=[]): # b的默认值指向一个空的列表,每次不带默认值都会指向这块内存
        print(id(b), end='---')
        b.append(a)
        return b
    
    print(func(1))  # 向默认的空列表里加入元素1 ,默认列表里已经是[1]
    print(func(2))  # 向默认的列表里加入元素2,默认列表里已经是[1,2]
    
    print(func(3, []))  # 向b指向新的一块内存地址的空列表里加入元素1 ,默认列表里还是[1,2]
    print(func(4))  # 向默认的列表里加入元素4,默认列表里已经是[1,2,4]
    
    
    运行结果:
    4352862280---[1]
    4352862280---[1, 2]
    4352860872---[3]
    4352862280---[1, 2, 4]

    3.3 关键字参数

      关键字参数是针对 函数的调用来讲的。 使用关键字参数来调用函数,就可以不按照次序来传递。

    def mymax(x, y):
        # 此时x = 20,y = 10
        the_max = x if x > y else y
        return the_max
    
    maxsum = mymax(y=10, x=20)               # 关键字传参,不按照定义的次序
    print(maxsum)
    
    计算结果
    20

    3.4 不定长参数 *args 

      不定长参数 *args ,接受位置参数,在函数中会转换为一个元祖。

    def func(*args): #这种定义会把传递的参数包成元组
            print(args,type(args))
    
    func(10,20)
    #结果:
    #(10, 20) <class 'tuple'>

     举一个相反的例子:

    def func(a,b):
            print('a=%d, b=%d' % (a,b) )
    
    a = (10, 20)
    func(*a) # 在调用函数使用`*`则会把元组解包成单个变量按顺序传入函数
    #结果:a=10, b=20

    总结:*号在定义函数参数时,传入函数的参数会转换成元组,如果 *号在调用时则会把元组解包成单个元素(元祖的形式)。

    3.5 不定长参数 **kwargs

    def func(**kw):#使用**定义参数会把传入参数包装成字典dict
            print(kw, type(kw) )
    
    func(a=10,b=20)#这种函数在使用时必须指定参数值,使用key=value这种形式
    #结果:{'b': 20, 'a': 10} <class 'dict'>

      举一个相反的列子

    def func(a,b):
            print('a=%d, b=%d' % (a,b) )
    
    d = {'a':10, 'b':20 }
    func(**d) #在调用时使用**会把字典解包成变量传入函数。

    总结:**号在定义函数参数时,传入函数的参数会转换成字典,如果 **号在调用时则会把字典解包成单个元素(k=v形式)。

    3.6 指定必须要传递一个参数

    def car(a=1, *, price): # * 代表后面的参数必须要传递
        print('waht')
    
    car(price='haha')       # 必须使用关键字参数,否则报错

    四、lambda函数

      一些函数功能比较简单,而我们不想去完整的去定义一个完整的参数,不想写函数名。

      就可以去用lambda函数。又叫做 匿名函数。

    def plus(x):
        return x + 1
    plus(19)
    
    # 进行函数的改写
    # 但是这种方法官方不建议,给匿名函数都命名了,还叫命名吗。。
    add = lambda x: x+1
    add(19)
    
    # 或写成这种
    print((lambda x: x + 1)(3))

    扩展:filter + lambda

    my_list = [1, 2, 3, 4, 5, 6]
    def odd(*L): new_list = [] for i in L: if i % 1 == 0: new_list.append(i) return new_list print(*my_list) # *把列表解开变成位置参数。 # 改装 ''' filter(func,iterable) 两个参数: 第一个参数 func :在这里写 函数就会显得冗长,那么我们就用lambda来写 第二个参数 iterbale :一个可迭代对象。 把迭代对象中每个元素拿到func中去执行,满足就留下来。 ''' # 第一步 lambda x: x % 2 == 0 # 第二步 返回的是一个可迭代的对象 filter(lambda x: x % 2 == 0, my_list) # 第3步 转换为列表 y = list(filter(lambda x: x % 2 == 0, my_list)) print(y)

      

      

      

  • 相关阅读:
    音频、摄像机操作
    调用系统相机及摄像机
    图片的放大缩小
    haxm intelx86加速模拟器的安装
    mac eclipse 下安装subclipse
    文件多线程下载实现
    windows与linux之间传输文件
    ZeroMQ接口函数之 :zmq_setsockopt –设置ZMQ socket的属性
    使用C语言在windows下一口气打开一批网页
    Net-SNMP是线程安全的吗
  • 原文地址:https://www.cnblogs.com/louhui/p/8921511.html
Copyright © 2011-2022 走看看