zoukankan      html  css  js  c++  java
  • 初学Python——函数

    一、函数定义

    1 def name( parameters):   #没有参数括号内可以为空
    2     "函数描述"                   #其实就是注释
    3     <代码块>              
    4     return [expression]   #没有返回值可以不加[]内容,也可以省略return

    def是定义函数的关键字,name是函数名,parameters是形参

    函数描述可以省略,但建议要有

    expression是返回值,可以没有返回值,也可以没有retrun。

    函数在return处结束。

    二、传参过程

    这里需要了解几个名词:位置参数、关键参数、默认参数

    1.位置参数:按照函数形式参数的顺序传递参数

    def func(x,y):
        print("x={0} y={1}".format(x,y))
     
    func(3,4)
    func(4,3)
    
    #输出:
    x=3 y=4
    x=4 y=3

    可以发现,位置参数的使用相当于C语言当中的函数调用方式。

    2.关键参数指的是在传递参数时,不必考虑形式参数的具体先后顺序,以“形式参数=实际参数”的形式传参。

    def func(x,y):
        print("x={0} y={1}".format(x,y))
     
    func(y=3,x=4)
    
    #输出结果:
    x=4 y=3

    3.默认参数:如果函数有默认参数,允许调用函数时不对默认参数传参(这时形参为默认值)

    def text2(x,y=2):#y为默认参数,非必须传递
        print(x,y)
    
    text2(1)   #可以这样调用
    text2(1,3) #也可以这样调用
    
    #输出结果:
    1 2
    1 3

    4.参数组

    如何向函数传递一个元组呢?

    需要参数组

    def text3(*args):
        print(args)
    
    text3(1,2,3)  #当使用参数组时,调用函数可以不传参
    #输出:
    (1,2,3)

    形参中*args是参数组,可以接收数量不固定的参数,也可以接收0个参数,并将这些参数组成一个元组在函数中使用。

    参数组可以在参数个数不确定的情况下使用。

    5.字典的传递

    def text5(**kwargs):#向函数传递字典
        print(kwargs)
    text5()                   #调用函数时可以不传参
    text5(name="liuwei",sex="man",index=3) #标准的传参传字典过程
    
    #输出结果:
    {“name”:"liuwei","sex":"man","index":3} #3是int型

    这种传参方式很容易和关键参数混淆。

    6.多种类型参数传递和优先级问题

    def text6(a,b=2,*args,**kwargs):
        print(a)
        print(b)
        print(args)
        print(kwargs)
    text6("woo",3,sex="m",hobby="aa")
    
    #输出结果:
    woo
    3
    ()
    {'sex': 'm', 'hobby': 'aa'}

    在定义函数时,形参应当遵循 普通参数-->默认参数-->参数组-->字典参数 的顺序

    在调用函数时,实参应当遵循 位置参数-->关键参数-->参数组-->字典参数 的顺序

    这样做为的是避免混淆。

    7.如何传递列表

    (1)位置参数

    def func(names):
        print(names)
        names[1] = 'jujinyi'
     
    names = ['aaron','jim']
    func(names)
    print(names)
    
    #输出:
    ['aaron', 'jim']
    ['aaron', 'jujinyi']
    View Code

    永久性改变了列表的值。如果想要对列表附件操作,可以用切片的方式

    def func(names):
        print(names)
        names[1] = 'jujinyi'
     
    names = ['aaron','jim']
    func(names)
    print(names)
    
    #输出:
    ['aaron', 'jim']
    ['aaron', 'jim']
    View Code

    (2)关键参数

    本质上和位置参数是一样的,没有什么区别

    (3)元组传递

    将传进去的元组使用list函数

    def func(*toppings):
        toppings = list(toppings)
        print(toppings)
     
    func('mushrooms','extra','cheese')
    func('mushrooms','extra')
     
    #输出:
    ['mushrooms', 'extra', 'cheese']
    ['mushrooms', 'extra']
    View Code

    三、返回值

    可以返回任何类型。基本数据类型(字符、整型等),列表(元组),字典,集合,甚至函数名也可以被返回

    如果返回多个值,所有的返回值会被封装成一个元组返回

    四、局部变量和全局变量

    1.定义 

    全局变量是定义在函数体外面的变量,局部变量是定义在函数体内的变量

    全局变量的作用域和生命周期从被定义开始直到程序结束,而局部变量则是从被定义到所在的函数结束。

    2.全局变量的使用

    全局变量当然可以在函数体外随意使用,在函数体内还会一样吗?

    a=6
    c=[1,2,3,4,5]
    def text():
        a=5
        b=10
        c[1]=0
        print("a={0},b={1},c={2}".format(a,b,c))
    
    text()
    print("a={0},b={1},c={2}".format(a,b,c))

    运行结果报错,问题出在最后一行:NameError: name 'b' is not defined。因为变量b是局部变量,只存在于函数内,在函数外已经不存在了。

    改一下:

    print("a={0},c={1}".format(a,c))
    
    #输出结果:
    a=5,b=10,c=[1, 0, 3, 4, 5]
    a=6,c=[1, 0, 3, 4, 5]

    发现了什么问题?a和c同为全局变量,都在函数内经过了修改,但是c被永久性的修改,a只是在函数内被修改,出来后被复原了。

    这是因为列表c在函数内外都是原件,而整型a在函数内修改,修改的是函数拷贝的临时变量,保证了全局变量的安全性。

    因此,可以用函数直接对列表、字典、集合等复杂类型的全局变量进行操作,但是无法在函数内对基本类型(如int,str,float等)的全局变量进行修改。

    3.如何在函数内修改基本类型的全局变量?

    Python提供了global关键字来进行声明

    a=6
    def text():
        global a #声明要在函数内修改全局变量
        a=10
        print(a)
    
    text()
    print(a)
    
    #运行结果:
    10
    10

    这样,全局变量就被修改了。

    虽然有这种方法,但是如果没有这种强烈需求的话,尽量不要这么做。

    五、高阶函数和嵌套函数

    1.以下两个条件满足其一就可称之为高阶函数:

    (1)把函数名当做实参传递给另一个函数

    (2)返回值中包含函数名

    2.函数可以嵌套,即函数体内可以定义函数

    六、递归

    定义:如果在函数内部可以调用自己,那么就称之为递归函数

    递归需要满足的特性:

    1.必须有一个明确的结束条件 (python内有预定的最大递归层数:999,程序的保护机制)
    2.每深入一层时,问题的规模应该减小
    3.递归的效率不高,递归层次过多容易导致栈溢出

  • 相关阅读:
    12月15日,progress_dispaly
    Android studio和Genymotion-VirtualBox的配合使用
    JDK7动态代理源码分析
    跟踪mqttv3源码(二)
    跟踪mqttv3源码(一)
    Spring自定义标签
    Eclipse发布Maven项目到远程服务器
    结合实际项目分析pom.xml
    Maven的安装环境配置
    PHP7新特性
  • 原文地址:https://www.cnblogs.com/V587Chinese/p/8873043.html
Copyright © 2011-2022 走看看