2019-07-09 函数的基本使用和参数

一、函数

  一、什么是函数

    函数就是具有某个具体功能的工具

  二、为什么要用函数

    减少代码冗余

    提供开发效率

    提高程序的扩展性

  三、定义一个函数

    def是定义函数的关键字

    函数名:函数名的命名规则与变量名的命名规则一样

        1.不能以关键字命名

        2.函数名也要做到见名之意

    函数在定义的时候只检测语法,不会执行代码

    调用函数的固定格式 :

      函数名+括号

      函数名只要遇到括号会立即执行函数代码

      代码中遇到函数名加括号  优先级最高

      先去执行函数  再去看下面的代码

二、函数的返回值    return

  函数内要想返回给调用者,必须用return

  有五种情况:

    1.不写return :函数默认返回None

def func():
    print(1+2)    #3

res1 = func()
print(res1)   #None

    2.只写return:也是返回None,除了有返回值,还可以直接结束整个函数运行,不管嵌套了几层循环都会被结束。

    print(1+2)不会执行,因为在它前面有个return,之后的所有代码都不会执行,最终结果只返回None

def func():
    return
    print(1+2)

res1 = func()
print(res1)     #None

    3.写return None:也是返回None,和只写return一样也会结束函数运行

def func():
    return None
    print(1+2)

res1 = func()
print(res1)      #None 

    4.写return 返回一个值:这个值可以是任何数据类型

def func():
    return '1234'
def func1():
    return [1,2,3]
def func2():
    return (1,2,3,4)
def func3():
    return {'name':'aaa'}

print(func(),func1(),func2(),func3())    #1234 [1, 2, 3] (1, 2, 3, 4) {'name': 'aaa'}

    5.写return 返回多个值:return 会自动将多个值以元组的形式返回给调用者

def func():
    return '1','2','3'
def func1():
    return [1,2,3],[4,5,6],[7,8,9]
def func2():
    return (1,2,3,4),(1,2,3)
def func3():
    return {'name':'aaa'},{'age':18}

print(func(),func1(),func2(),func3())   #('1', '2', '3') ([1, 2, 3], [4, 5, 6], [7, 8, 9]) ((1, 2, 3, 4), (1, 2, 3)) ({'name': 'aaa'}, {'age': 18})

    如果不想以元组的方式返回,那就手动加上你想返回的数据类型的符号

def func4():
    return [(1,2,3,4),(1,2,3)]

print(func4())    #[(1, 2, 3, 4), (1, 2, 3)]

  总结:1.所有函数都有返回值,不写return返回值是None

     2.光写return 或者return None不是考虑函数返回值,而是函数结束运行

三、函数参数    四种:位置参数、关键字参数、默认值参数、可变长参数(不定长参数)

  函数参数的两大类型:

    形参:在函数定义阶段  括号内写的变量名,叫做该函数的形式参数

    实参:在函数调用阶段  括号内传入的实际值,叫做实际参数

  形参与实参的关系:

    形参就相当于变量名,实参就相当于变量名的值

    函数调用传参的过程,就是给形参赋值的过程

  注意:形参和实参的绑定关系只在函数的调用阶段有效,函数运行结束关系自动解除,只有在函数内部有效,函数外部无任何影响

  现在我们可以得出函数的简易结构:

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

      '''函数注释'''

      函数代码体1

      函数代码体2

      。。。

      return  函数的返回值

  1.位置参数:在函数定义阶段按照位置从左往右依次书写的变量名,叫做位置形参

  位置形参:在调用的时候  必须为其传值

def func(x,y):
    return x+y

res = func(1,2)
print(res)      #3

   位置实参在调用函数的时候,多一个参数,少一个参数都不行,传入的参数要按照位置一一对应传给形参

  2.关键字参数:在函数调用阶段,给变量名赋值

def func(x,y):
    return x+y

res = func(3,y=2)
print(res)        #5

  总结:

    注意:在函数调用阶段,位置参数和关键字参数可以混合使用

    但必须保证:

        1.位置参数必须在关键字参数前面(越短的越靠前,越长的越复杂的越靠后),在函数定义阶段这个也适用

        2.同一个参数不能被多次赋值

  3.默认值参数:在函数定义阶段,给变量名赋值

    在调用函数阶段,如果不给该参数(变量名)传值,就默认使用在定义阶段赋值的值。

    在调用函数阶段,如果给该参数(变量名)传值,就使用你传的值。

       在定义阶段也是位置参数放在前面,默认值参数放在后面(越短的越在前面,越长的越在后面)

#在调用的时候,不给y传值
def func(x,y=3):
    return x+y

res = func(3)
print(res)     #6

#在调用的时候,给y传值
def func(x,y=3):
    return x+y

res = func(3,y=6)
print(res)      #9

  易错题分析(这里一直是在使用唯一一个列表,所以会一直往一个列表里面添加)

def info(username,hobby,l=[]):
    
    l.append(hobby)
    print('%s 的爱好是 %s'%(username,l))
info('jason','study')
info('tank','生蚝')
info('kevin','喝腰子汤')
info('egon','女教练')

#结果
#jason 的爱好是 ['study']
#tank 的爱好是 ['study', '生蚝']
#kevin 的爱好是 ['study', '生蚝', '喝腰子汤']
#egon 的爱好是 ['study', '生蚝', '喝腰子汤', '女教练']

  纠正(在调用info的时候,默认传值l = None,函数体里面if判断如果l == None,就会变成l = [],每一次调用都会生成一个)

def info(username,hobby,l=None):
    if l == None:
        l = []
    l.append(hobby)
    print('%s 的爱好是 %s'%(username,l))
info('jason','study')
info('tank','生蚝')
info('kevin','喝腰子汤')
info('egon','女教练')

#结果
#jason 的爱好是 ['study']
#tank 的爱好是 ['生蚝']
#kevin 的爱好是 ['喝腰子汤']
#egon 的爱好是 ['女教练']

  总结:函数无论在什么地方被调用,都会到函数定义阶段去执行代码,所需要值都是往函数定义阶段上面找

     函数在定义阶段,内部所使用的的变量都已经全部初始化完毕了,不会因为后面调用位置的改变而影响到内部的值

   4.可变长参数:在调用的时候,实参传递的个数不固定,可能会传递多了,也可能会传递少了,在定义的时候,形参也可能会这样,我们用*和**来接收多余的参数

    1.站在形参的角度看  *

      形参中的*会将实参中的多余位置参数统一放在元组中,然后传递给后面的形参名

      *在形参中只能接受多余的位置参数,其他的类型参数不行

def func(x,y,*z):
    print(x,y,z)
  
func(1,2,3,4,5,6)    #1 2 (3, 4, 5, 6)

    2.站在实参的角度看  *

      实参中的*会将元组、列表、集合、字符串打散,然后一一传入到形参中,打散之后的实参个数要和形参个数一致,不然就会报错 

      func(*(1,2,3)) 等价于   func(1,2,3)

def func(x,y,z):
    print(x,y,z)

func(*(1,2,3))   #1 2 3

    3.站在形参角度看 **

      形参中的 **会将多余的关键字参数(实参)统一放在一个字典中,然后传递给后面的形参名

      **在形参中只接受多余的关键字参数,其余类型参数不行

def func(x,y,**z):
    print(x,y,z)

func(1,2,a=3,b=4)   #1 2 {'a': 3, 'b': 4}

    4.站在实参的角度看 **      将实参中传入的字典转换成  key = value

      func(**{'x':1,'y':2,'z':3})   等价于func(x=1,y=2,z=3)      

      特别重要的一点:在实参中传参的时候这个字典的key要和形参中的变量名取名一致

def func(x,y,z):
    print(x,y,z)

func(**{'x':1,'y':2,'z':333})   #1 2 333

  总结 *和**

    *在形参中能够接受实参中多余的位置参数,并且把他们统一放在一个元组中并赋值给*后面的变量名

    **在形参中能够接受实参中多余的关键字参数,并且把他们统一成一个字典并赋值给**后面的变量名

    

    *在实参中能够将列表,元组,字符串,集合打散成位置参数形式传递给形参

    **在实参中能够将字典打散成key = value 的形式  ,以关键字参数传递给形参

   

本节总结:

    1.关键字参数是在实参中设定

    2.默认参数是在形参中设定   

原文地址:https://www.cnblogs.com/wangcuican/p/11159254.html