• python学习笔记day09 函数


    函数:

    函数的定义和函数的调用不是一回事,程序执行时,遇到定义函数,只会执行定义函数名处,里面的函数体这个时候是不会执行的;

    只有到调用函数处才会执行里面的函数体;

    返回值:

    没有返回值: 无 return;   -----返回None

                           只有 return;----返回None

                           return None----返回None

    有返回值:  可以返回任意数据类型;

                        返回多个值时,可以用多个变量接收,但是变量要对应,不多不少;或者只用一个变量接收也可以;

    参数

    定义函数处的参数为形参,形参可以包括位置参数和关键字参数(又称默认参数)且位置参数必须在关键字参数之前;

    调用函数处的参数为实参,实参也包括位置参数和关键字参数,位置参数在前,关键字参数在后;

    并且上述两种参数都可以只用位置参数,或者只使用关键字参数,当混用时需要满足位置参数在前的原则;

    def func(a,b):  #形参仅使用位置参数;
        print(a+b)
    func(1,2)   #实参采用位置参数,一一对应 a=1;b=2
    func(1,b=2) #位置参数和关键字参数同时使用,位置参数在前;
    func(b=1,a=2) #使用关键字参数,可以不按形参顺序赋值;
    def func(a,b=2):  #形参同时使用位置参数和关键字参数,位置参数在前;
        print(a+b)
    
    func(1,2)   #实参采用位置参数,一一对应 a=1;b=2
    func(1,b=4) #位置参数和关键字参数同时使用,位置参数在前;
    func(b=1,a=2) #使用关键字参数,可以不按形参顺序赋值;
    def func(a=3,b=2):  #形参使用关键字参数;
        print(a+b)
    
    func(1,2)   #实参采用位置参数,一一对应 a=1;b=2
    func(1,b=4) #位置参数和关键字参数同时使用,位置参数在前;
    func(b=1,a=2) #使用关键字参数,可以不按形参顺序赋值;

    也就是不管定义时形参采取什么样的参数形式,调用时实参可以采用上述三种方式;

    动态参数-- *args ----传入的值被当成tuple处理(按照位置参数)

    定义时采用动态参数 *args 调用时可以传无数个参数,但是需要按照位置参数进行传递;

    比如我们想计算很多个数的和,可能计算三个数,也可能计算100个数,,,

    def func(*args):
        sum=0
        for i in args:
            sum+=i
        print(sum)
    func(1,2,3,4)  #需按照位置参数进行传递
    func(2,3,4,5,6,7,8)

    动态参数*args 和位置参数,关键字参数放一起时的顺序:位置参数,*args ,关键字参数;

    def func(a,*args,b=10):
        sum=0
        for i in args:
            sum+=i
        print(sum+a-b)
    func(1,2,3,4,b=2)    # 传递进去时a被赋值为1,而2,3,4 传给了动态参数args,b的值采用关键字参数赋值为2
    func(2,3,4,5,6,7,8)  # 传递进去时a被赋值为2,而3,4,5,6,7,8 传给了动态参数args,b的值采用默认值10

    动态参数-- **kwargs-----传入的值当成字典处理(按照关键字参数)

    def func(**kwargs):  #动态参数**kwargs,传入的值当成字典处理
        print(kwargs)
    func(a=1,b=2,c=3)

    当位置参数,动态参数*args,关键字参数,动态参数**kwargs同时存在时:

    def func(a,*args,b=2,**kwargs): #位置参数,动态参数*args,关键字参数,动态参数**kwargs
        print(a)
        print(args)      #传入args的值被当成list;
        print(b)
        print(kwargs)  #传入**kwargs的值被当成字典
    
    func(1,2,3,4,5,b=7,c=9,d=2)  # 1->a;   2,3,4,5-->args;     7---->b        c:2,d:9----> kwargs;
    func(1,2,3,4,5,c=8,d=9)      # 1->a;   2,3,4,5-->args;     2(默认)(而不是前面的5)---->b        c:2,d:9----> kwargs;

    运行结果:

    顺序:位置参数,动态参数*agrs,关键字参数,动态参数**kwargs 

     调用函数处使用* 和**: 将tuple或者字典打散;(定义函数处再将其重新组合)

    def func(*args):
        sum=0
        for i in args:
            sum+=i
        print(sum)
    nums=[1,2,3,4,5]
    func(nums[0],nums[1],nums[2],nums[3],nums[4])
    func(*nums)

    相当于调用函数处将nums列表的元素打散之后传给动态参数*args,定义函数处,将打散的数再重新组合乘一个tuple

    再来看调用函数处使用** 将字典打散:

    def func(**kwargs):
        print(kwargs)
    
    dic={'a':1,'b':2,'c':3}
    func(**dic)

    如果定义函数处参数的值是一个可变数据类型,每次函数调用不传参数,则会一直共用这个可变数据类型的资源!!!

    之前一直没搞懂的问题,现在终于懂了:

    def func(L=[]):  #使用的默认参数的值是一个可变数据类型list
        L.append(1)
        print(L)
    func()    #L=[1]
    func([])  #L=[1]  #因为现在调用函数自己传了一个参数[] 不是原来的列表(已经在[]的基础上append了一个1)
    func()    #L=[1,1] #使用的仍然是默认参数的值-->可变list 还是使用的原来那个list,也就是地址没变,但是list值变了,func()--->L=[1],还是,现在又增加了一个1--->[1,1]
    fun()     #L=[1,1,1] 经过上面两个func()后默认参数还是指向原来的list,只不过这个list会变,不停的append

    再举一个例子,仍然是定义函数处使用的默认参数的值为可变数据类型:

    形参中的默认参数是可变数据类型,实参不传参,则始终操作的都是同一个数据类型(可变),所以默认参数这个可变数据类型的值是会发生改变的!!!

    def func(k,dic={}):  # 位置参数k,关键字参数dic 是一个可变数据类型:字典
        dic[k]='value'
        print(dic)
    
    func(1)  #传的位置参数1赋值给k 作为字典的键, 值为value--->dic={1:'value'}
    func(2)  #字典仍使用默认参数,使用原来那个地址,但是这个字典不再是空的了,因为它会变化!--dic={1:'value',2:'value'}
    func(3)  #dic={1:'value',2:'value'3,'value'}

    talk is cheap,show me the code
  • 相关阅读:
    JDOM入门实例:读取与创建xml文档
    C++构造函数/析构函数/拷贝构造函数/深拷贝浅拷贝解析
    java类的访问权限
    hive怎样决定reducer个数
    hive Cli常用操作(翻译自Hive wiki)
    hive local hadoop特性
    hive数据操作(翻译自Hive wiki+实例讲解)
    hive的hive.exec.parallel参数说明
    hive数据类型(翻译自Hive Wiki)
    hive 创建/删除/截断 表(翻译自Hive wiki)
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9539025.html
Copyright © 2020-2023  润新知