• Python_函数


    定义一个函数

    你可以定义一个由自己想要功能的函数,以下是简单的规则:

    • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
    • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
    • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    • 函数内容以冒号起始,并且缩进。
    • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None

    语法

    def functionname( parameters ):   #定义一个函数,functionname是函数名,函数名不能重复
       "函数_文档字符串"
       function_suite                 #函数体
       return [expression]            #return返回值,若无return,则该函数返回为None

    参数

    以下是调用函数时可使用的正式参数类型:

    • 位置参数
    • 默认参数
    • 关键字参数
    • 不定长参数(可变参数)

    位置参数

    位置参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样,位置参数为必填项。

    调用plus函数,需要传入2个参数,否则报语法错误,如下:

    def plus(x,y):   #函数名plus,形参:x,y,简单来说就是函数接收的参数
        print(x+y)    #函数体,打印x+y的值
    plus(3, 4)       #函数调用,3和4就是实参,就是传入的参数,执行结果是:7

    传入错误的参数个数,如下:

    复制代码
    def plus(x,y):
        print(x+y)
    plus(3, 4, 5)
    报错信息如下:
      File "E:/python_workspace/base-code/day4/函数my.py", line 69, in <module>
        plus(3, 4, 5)
    TypeError: plus() takes 2 positional arguments but 3 were given
    复制代码

    不按照正确的顺序传入参数,打印的结果如下:

    def plus(name, age):
        print(name, age)
    plus(12, 'lhl')       #name=12,age=lhl,明显输入不合法

    位置参数 - 关键字传参

    使用位置参数调用函数时,如果有多个位置参数的话,记不住哪个位置传哪个了怎么办,可以使用位置参数的名字来指定调用,如下:

    复制代码
    #有多个位置参数,可能会越来越多,使用固定的位置参数时,记不住或者传错了位置,可以使用位置参数的名字来指定调用,叫关键字传参
    def plus(name, age, sex, city, phone, money, color, time):
        print(name, age, sex, city, phone, money, color, time)
    plus('zhangsan',18,  'man', color='black', money=44444, time=time.time(),phone=13400000000,city='beijing')
    
    执行结果显示与函数参数位置对应: zhangsan
    18 man beijing 13400000000 44444 black 1497020260.7982826
    复制代码

    默认参数

    调用函数时,默认参数的值如果没有传入,则被认为是默认值。这样就算你在调用的时候没传入这个参数,它也是有值的,默认参数不是必填项,如下:

    def plus(name, sex, age=18):  #age位默认参数,默认值是18
        print(name, sex, age)
    plus('zhangsan','man')       #调用函数时,未输入age的值,则默认age值为18
    执行结果:
    zhangsan man 18

    调用函数时,给默认参数传值,且默认参数在位置参数后面,如下:

    def plus(name, sex, age=18):  #age位默认参数,默认值是18,age必须位于位置参数后面
        print(name, sex, age)
    plus('zhangsan', 'man', age=28)       #调用函数时,输入age的值,则默认age为输入的值
    执行结果:
    zhangsan man 28

     调用函数时,默认参数位于 位置参数前面,则报语法错误,信息如下:

    复制代码
    def plus(name, age=18, sex):  #age位默认参数,默认值是18,age必须位于位置参数sex 前面,则语法错误
        print(name, sex, age)
    plus('zhangsan', 'man')       #调用函数时,未输入age的值,则默认age的值
    报错信息如下:
      File "E:/python_workspace/base-code/day4/函数my.py", line 67
        def plus(name, age=18, sex):  #age位默认参数,默认值是18,age必须位于位置参数sex 前面,则语法错误            ^
    SyntaxError: non-default argument follows default argument
    复制代码

    非固定参数:

    上面的两种位置参数和默认参数都是参数个数是固定的,如果说我一个函数,参数不是固定的,我也不知道以后这个函数会扩展成啥样,可能参数越来越多,这个时候如果再用固定的参数,那后面程序就不好扩展了,这时候就可以用非固定参数了,非固定参数有两种,一种是可变参数,一种是关键字参数。

    可变参数:

    可变参数用*来接收,后面想传多少个参数就传多少个,如果位置参数、默认值参数、可变参数一起使用的的话,可变参数必须在位置参数和默认值参数后面。可变参数也是非必传的。

    复制代码
    def post(*args):     #参数个数不固定时,使用*args可变参数,参数组,返回结果是元组,也为非必填参数
        print(args)      #打印结果是元组:('001', 'login', 'post'),该函数没有返回值,返回值为None
    post()               #调用函数,不传参数,打印结果为空的元组
    print(post('001', 'login', 'post'))
    
    执行结果:
    ()
    ('001', 'login', 'post')
    None
    复制代码

    可变参数与位置参数、默认参数一起使用,如下:

    复制代码
    #可变参数使用*来接收,*可变参数名, 必须放在位置参数、默认参数后面,默认参数必须放在位置参数后面
    def plus(name, sex, age=18, *args):
        print(name)
        print(sex)
        print(age)
        print(args)
    plus('zhangsan', 'man', 'black', 44444, 13400000000, 'beijing')  #默认参数可以不传
    
    执行结果:
    zhangsan
    man
    black
    (44444, 13400000000, 'beijing')
    复制代码

    关键字参数:

    关键字参数使用**来接收,后面的参数也是不固定的,不限长度,也可以和位置参数、默认参数、可变参数一起使用,关键字参数必须在最后面。

    使用关键字参数的话,调用的时候必须使用关键字传参。关键字参数也是非必传的。如下:

    复制代码
    def other(**kwargs):  #关键字参数,传入值通过key=value方式传入,返回结果是字典类型,也为非必填参数
        print(kwargs)
    other(name='byz', age=18)
    
    执行结果:
    {'name': 'byz', 'age': 18}
    复制代码

    与位置参数、默认参数、可变参数一起使用,如下:

    复制代码
    def other(name, age, sex='', *args, **kwargs):  #关键字参数,传入值通过key=value方式传入,返回结果是字典类型,也为非必填参数
        print(name)
        print(age)
        print(sex)
        print(args)
        print(kwargs)
    other('zhangsan', 24, 'red', 'sun', 110, city='beijing', score=99)
    
    执行结果:
    zhangsan
    24
    red
    ('sun', 110)
    {'city': 'beijing', 'score': 99}
    复制代码

    return 语句

    return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,下例便告诉你怎么做:

    复制代码
    def sum(args1, args2):
        total = args1 + args2
        print('total :', total)  #函数内打印出total的值
        return total            #函数返回total,若输入的args1、args2位int类型, 则该函数返回int;若输入的位int+float,则返回结果为float
    print(sum(12, 13.1))
    
    执行结果:
    total : 25.1
    25.1
    复制代码

    全局变量和局部变量

    定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

    局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。全局变量如果要在函数中修改的话,需要加global关键字声明,如果是list、字典和集合的话,则不需要加global关键字,直接就可以修改,如下:

    复制代码
    name = 'marry'  #字符串全局变量
    names = []      #list全局变量
    print(name)
    print(names)
    def test():
        global name        #修改全局变量-name的值就需要用global关键字声明下name为全部变量
        name = 'Sriba'      #修改全局变量name的值
        names.append(name)  #修改全局变量names的值
        return names
    test()
    print('修改后', name)
    print('修改后names', names)
    
    执行结果:
    marry
    []
    修改后 Sriba
    修改后names ['Sriba']
    复制代码

    修改全局变量List类型的值,如下:

    复制代码
    names = [1, 2, 3, 4]     #list全局变量
    print(names)
    def test():
        names = ['a', 'b', 'c', 'd']     #修改全局变量names的值不需要用global关键字声明, 直接进行修改
        return names
    print('修改后names:', test())
    
    执行结果:
    [1, 2, 3, 4]
    修改后names: ['a', 'b', 'c', 'd']
    复制代码

    递归调用

    递归函数:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

    递归函数的优点是:定义简单、逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,循环的逻辑不如递归清晰。

    使用递归函数需要注意防止栈溢出。函数调用时通过栈(stack)这种数据结构实现,每当进入一个函数调用,栈就会加一层栈帧,每当函数烦死,栈就减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

    复制代码
    def login():
        username = input('请输入用户名:').strip()
        if username != '' :
            if username == 'admin':
                return username        #登录成功则返回登录的用户名信息
            else:
                print('用户名不存在,请重新输入')
                return login()       #递归调用login函数,若登录成功,则返回输入的用户名
        else:
            print('用户名、密码不能为空')
    复制代码

    栈溢出,可以尝试操作以下代码fct(10000):

    def fct(n):
        if n == 1:
            return 1
        else:
            return n * fct(n-1) 

    高阶函数:

    既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

    简单举例:

    def add(a, b, f):
        return f(a) + f(b)
    print(add(-5, 6, abs))    #此时f=abs(num)

    嵌套函数

    复制代码
    def test():
        i=0
        def a():
            print locals()
        a()
        print i
     
    test()
    复制代码

    这段,locals()的值为空,说明内嵌的a函数没有默认引入i

    复制代码
    def test():
        i=0
        def a():
            print locals()
            print i
        a()
        print i
     
    test()
    复制代码

    这段,locals()有了i的字典,说明解释器自动引入了i

    复制代码
    def test():
        i=0
        def a():
            i+=1
            print locals()
            print i
        a()
        print i
     
    test()
    复制代码

    这段出错,提示i引用在了i声明之前

    内部函数可以引用外部函数变量,暂时没找到修改外部函数变量值方法

     

    
    

    参数

    以下是调用函数时可使用的正式参数类型:

    • 位置参数
    • 默认参数
    • 关键字参数
    • 不定长参数(可变参数)

    位置参数

    位置参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样,位置参数为必填项。

    调用plus函数,需要传入2个参数,否则报语法错误,如下:

    def plus(x,y):   #函数名plus,形参:x,y,简单来说就是函数接收的参数
        print(x+y)    #函数体,打印x+y的值
    plus(3, 4)       #函数调用,3和4就是实参,就是传入的参数,执行结果是:7

    传入错误的参数个数,如下:

    复制代码
    def plus(x,y):
        print(x+y)
    plus(3, 4, 5)
    报错信息如下:
      File "E:/python_workspace/base-code/day4/函数my.py", line 69, in <module>
        plus(3, 4, 5)
    TypeError: plus() takes 2 positional arguments but 3 were given
    复制代码

    不按照正确的顺序传入参数,打印的结果如下:

    def plus(name, age):
        print(name, age)
    plus(12, 'lhl')       #name=12,age=lhl,明显输入不合法

    位置参数 - 关键字传参

    使用位置参数调用函数时,如果有多个位置参数的话,记不住哪个位置传哪个了怎么办,可以使用位置参数的名字来指定调用,如下:

    复制代码
    #有多个位置参数,可能会越来越多,使用固定的位置参数时,记不住或者传错了位置,可以使用位置参数的名字来指定调用,叫关键字传参
    def plus(name, age, sex, city, phone, money, color, time):
        print(name, age, sex, city, phone, money, color, time)
    plus('zhangsan',18,  'man', color='black', money=44444, time=time.time(),phone=13400000000,city='beijing')
    
    执行结果显示与函数参数位置对应: zhangsan
    18 man beijing 13400000000 44444 black 1497020260.7982826
    复制代码

    默认参数

    调用函数时,默认参数的值如果没有传入,则被认为是默认值。这样就算你在调用的时候没传入这个参数,它也是有值的,默认参数不是必填项,如下:

    def plus(name, sex, age=18):  #age位默认参数,默认值是18
        print(name, sex, age)
    plus('zhangsan','man')       #调用函数时,未输入age的值,则默认age值为18
    执行结果:
    zhangsan man 18

    调用函数时,给默认参数传值,且默认参数在位置参数后面,如下:

    def plus(name, sex, age=18):  #age位默认参数,默认值是18,age必须位于位置参数后面
        print(name, sex, age)
    plus('zhangsan', 'man', age=28)       #调用函数时,输入age的值,则默认age为输入的值
    执行结果:
    zhangsan man 28

     调用函数时,默认参数位于 位置参数前面,则报语法错误,信息如下:

    复制代码
    def plus(name, age=18, sex):  #age位默认参数,默认值是18,age必须位于位置参数sex 前面,则语法错误
        print(name, sex, age)
    plus('zhangsan', 'man')       #调用函数时,未输入age的值,则默认age的值
    报错信息如下:
      File "E:/python_workspace/base-code/day4/函数my.py", line 67
        def plus(name, age=18, sex):  #age位默认参数,默认值是18,age必须位于位置参数sex 前面,则语法错误            ^
    SyntaxError: non-default argument follows default argument
    复制代码

    非固定参数:

    上面的两种位置参数和默认参数都是参数个数是固定的,如果说我一个函数,参数不是固定的,我也不知道以后这个函数会扩展成啥样,可能参数越来越多,这个时候如果再用固定的参数,那后面程序就不好扩展了,这时候就可以用非固定参数了,非固定参数有两种,一种是可变参数,一种是关键字参数。

    可变参数:

    可变参数用*来接收,后面想传多少个参数就传多少个,如果位置参数、默认值参数、可变参数一起使用的的话,可变参数必须在位置参数和默认值参数后面。可变参数也是非必传的。

    复制代码
    def post(*args):     #参数个数不固定时,使用*args可变参数,参数组,返回结果是元组,也为非必填参数
        print(args)      #打印结果是元组:('001', 'login', 'post'),该函数没有返回值,返回值为None
    post()               #调用函数,不传参数,打印结果为空的元组
    print(post('001', 'login', 'post'))
    
    执行结果:
    ()
    ('001', 'login', 'post')
    None
    复制代码

    可变参数与位置参数、默认参数一起使用,如下:

    复制代码
    #可变参数使用*来接收,*可变参数名, 必须放在位置参数、默认参数后面,默认参数必须放在位置参数后面
    def plus(name, sex, age=18, *args):
        print(name)
        print(sex)
        print(age)
        print(args)
    plus('zhangsan', 'man', 'black', 44444, 13400000000, 'beijing')  #默认参数可以不传
    
    执行结果:
    zhangsan
    man
    black
    (44444, 13400000000, 'beijing')
    复制代码

    关键字参数:

    关键字参数使用**来接收,后面的参数也是不固定的,不限长度,也可以和位置参数、默认参数、可变参数一起使用,关键字参数必须在最后面。

    使用关键字参数的话,调用的时候必须使用关键字传参。关键字参数也是非必传的。如下:

    复制代码
    def other(**kwargs):  #关键字参数,传入值通过key=value方式传入,返回结果是字典类型,也为非必填参数
        print(kwargs)
    other(name='byz', age=18)
    
    执行结果:
    {'name': 'byz', 'age': 18}
    复制代码

    与位置参数、默认参数、可变参数一起使用,如下:

    复制代码
    def other(name, age, sex='', *args, **kwargs):  #关键字参数,传入值通过key=value方式传入,返回结果是字典类型,也为非必填参数
        print(name)
        print(age)
        print(sex)
        print(args)
        print(kwargs)
    other('zhangsan', 24, 'red', 'sun', 110, city='beijing', score=99)
    
    执行结果:
    zhangsan
    24
    red
    ('sun', 110)
    {'city': 'beijing', 'score': 99}
    复制代码

    return 语句

    return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,下例便告诉你怎么做:

    复制代码
    def sum(args1, args2):
        total = args1 + args2
        print('total :', total)  #函数内打印出total的值
        return total            #函数返回total,若输入的args1、args2位int类型, 则该函数返回int;若输入的位int+float,则返回结果为float
    print(sum(12, 13.1))
    
    执行结果:
    total : 25.1
    25.1
    复制代码

    全局变量和局部变量

    定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

    局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。全局变量如果要在函数中修改的话,需要加global关键字声明,如果是list、字典和集合的话,则不需要加global关键字,直接就可以修改,如下:

    复制代码
    name = 'marry'  #字符串全局变量
    names = []      #list全局变量
    print(name)
    print(names)
    def test():
        global name        #修改全局变量-name的值就需要用global关键字声明下name为全部变量
        name = 'Sriba'      #修改全局变量name的值
        names.append(name)  #修改全局变量names的值
        return names
    test()
    print('修改后', name)
    print('修改后names', names)
    
    执行结果:
    marry
    []
    修改后 Sriba
    修改后names ['Sriba']
    复制代码

    修改全局变量List类型的值,如下:

    复制代码
    names = [1, 2, 3, 4]     #list全局变量
    print(names)
    def test():
        names = ['a', 'b', 'c', 'd']     #修改全局变量names的值不需要用global关键字声明, 直接进行修改
        return names
    print('修改后names:', test())
    
    执行结果:
    [1, 2, 3, 4]
    修改后names: ['a', 'b', 'c', 'd']
    复制代码

    递归调用

    递归函数:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

    递归函数的优点是:定义简单、逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,循环的逻辑不如递归清晰。

    使用递归函数需要注意防止栈溢出。函数调用时通过栈(stack)这种数据结构实现,每当进入一个函数调用,栈就会加一层栈帧,每当函数烦死,栈就减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

    复制代码
    def login():
        username = input('请输入用户名:').strip()
        if username != '' :
            if username == 'admin':
                return username        #登录成功则返回登录的用户名信息
            else:
                print('用户名不存在,请重新输入')
                return login()       #递归调用login函数,若登录成功,则返回输入的用户名
        else:
            print('用户名、密码不能为空')
    复制代码

    栈溢出,可以尝试操作以下代码fct(10000):

    def fct(n):
        if n == 1:
            return 1
        else:
            return n * fct(n-1) 

    高阶函数:

    既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

    简单举例:

    def add(a, b, f):
        return f(a) + f(b)
    print(add(-5, 6, abs))    #此时f=abs(num)
  • 相关阅读:
    HDU 2089 不要62 (数位DP)
    数位DP总结
    怒刷DP之 HDU 1160
    将时间转为几小时前,几周前,几天前等
    link与import的区别
    什么是虚拟DOM?为啥虚拟DOM可以提升性能?
    前端面试问题2
    【转载】什么是闭包? 闭包的优缺点 闭包的应用场景
    小程序发布审核不通过
    前端面试常问 问题总结
  • 原文地址:https://www.cnblogs.com/wang-xd/p/7580253.html
Copyright © 2020-2023  润新知