欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python函数进阶

程序员文章站 2024-03-17 16:56:52
...

1.函数的进阶

  1. *的魔性用法

    # *的魔性用法: (函数中)
    
    def func(*args,**kwargs):
        print(args)  # (1, 2, 3,'太白', 'wusir', '景女神')
        print(kwargs)
    
    l1 = [1, 2, 3]
    l2 = ['太白', 'wusir', '景女神']
    func(l1,l2)
    func(*l1,*l2)  # 当函数的执行时:*iterable 代表打散。
    func(*[1, 2, 3],*(11,22),*'fdsakl')  # 当函数的执行时:*iterable 代表打散。
    
    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    func(**{'name':"alex"},**{'age': 73,'hobby': '吹'})
    当函数的执行时:**dict 代表打散。
    
    # 函数外:处理剩余元素
    a,b,*c = [1,2,3,4,5] # a = 1 , b = 2 , c = [3, 4, 5] 
    a,*c,b, = [1,2,3,4,5] # a = 1 , b = 5 , c = [3, 4, 5]
    a,*c = range(5) # a = 0 , c = [1, 2, 3, 4]
    a,*c,b = (1,2,3,4,5,6) # a = 1 , b = 6 , c = [2, 3, 4, 5]
    print(a,c,b)
  2. 形参角度的最终顺序

    # *args的位置
    # *args不能放在位置参数前面,a,b取不到值
    def func(*args,a,b,sex='man',):
        print(a)
        print(b)
        print(sex)
        print(args)
        # print(kwargs)
    func(1,2,4,5,6)
    
    # args如果想要接收到值之前,肯定要改变sex默认参数。
    def func(a,b,sex='man',*args):
        print(a)
        print(b)
        print(sex)
        print(args)
        # print(kwargs)
    func(1,2,4,5,6)
    
    def func(a,b,*args,sex='man'):
        print(a)
        print(b)
        print(sex)
        print(args)
        # print(kwargs)
    func(1,2,4,5,6)
    func(1,2,4,5,6,sex='women')
    
    # **kwargs
    # 位置参数,*args,默认参数,**kwargs
    def func(a,b,*args,sex='man',**kwargs,):
        print(a)
        print(b)
        print(sex)
        print(args)
        print(kwargs)
    func(1,2,4,5,6,name='太白',age=18)
  3. 从空间角度研究函数

    全局名称空间: py文件运行时开辟的,存放的是执行的py文件(除去函数内部)的所有的变量与值(地址)的对应关系,整个py文件结束之后,才会消失。

    临时(局部)名称空间: 函数执行时,在内存中临时开辟的一个空间,存放的函数中的变量与值的对应关系,随着函数的结束而消失。

    内置名称空间:input,print,内置函数等。

  4. 取值顺序加载顺序

    加载顺序:上面这三个空间,谁先加载到内存。

    内置名称空间 ----》 全局名称空间 ----》 (函数执行时)临时名称空间

    取值顺序:(就近原则)

  5. 作用域

    全局作用域:全局名称空间,内置名称空间。

    局部作用域:局部名称空间。

  6. 内置函数:globals,locals

    """此文件研究的是内置函数 globals locals"""
    name = 'alex'
    l1 = [1, 2, 3]
    def func():
        age = '18'
    print(globals()) # 全局作用域所有的内容
    print(locals())  # 当前位置
    
    name = 'alex'
    l1 = [1, 2, 3]
    def func():
        age = '18'
        oldboy = '老男孩教育'
        print(globals()) # 全局作用域所有的内容
        print(locals())  # 当前位置的变量与值的对应关系
    func()
    
    name = 'alex'
    l1 = [1, 2, 3]
    def func():
        age = '18'
        oldboy = '老男孩教育'
        def inner():
            name_class = 'python23期'
            print(globals()) # 全局作用域所有的内容
            print(locals())  # 当前位置的变量与值的对应关系
        inner()
    func()
  7. 高阶函数(嵌套函数)

    # 例1:
    def func1():
        print('in func1')
        print(3)
    def func2():
        print('in func2')
        print(4)
    func1()
    print(1)
    func2()
    print(2)
    '''结果
    in func1
    3
    1
    in func2'
    4
    2
    '''
    
    # 例2:
    def func1():
        print('in func1')
        print(3)
    def func2():
        print('in func2')
        func1()
        print(4)
    print(1)
    func2()
    print(2)
    '''结果
    1
    in func2
    in func1
    3
    4
    2
    '''
    # 例3:
    def fun2():
        print(2)
        def func3():
            print(6)
        print(4)
        func3()
        print(8)
    print(3)
    fun2()
    print(5)
    '''结果
    3 2 4 6 8 5
    '''
  8. 关键字:global,nonlocal

    在函数内部无法修改全局变量
    count = 0
    def func():
        count += 1
    func()
    # 报错: UnboundLocalError: local variable 'count' referenced before assignment
    # 解释器认为:如果你在局部作用域对一个变量进行修改了,
    # 你在局部作用域已经定义好这个变量了。
    
    global
    1. 可以在局部作用域声明一个全局变量。
    # global 可以在函数内部创建一个全局变量
    def func():
        global name
        name = 1
        print(globals())
        name += 1
        print(globals())
    func()
    print(name)
    print(globals())
    # 通过globals 可以查看到局部名称空间没有name变量,而是在全面名称空间内
    
    2. 可以修改全局变量。
    # global 可以在函数内部修改全局变量
    count = 0
    def func():
        global count
        count += 1
    print(count)
    func()
    print(count)
    # 通过运行函数,可以看出函数对全局变量count及逆行了修改
    
    nonlocal
    1. 不能操作全局变量。
    2. 可以对父级作用域的变量进行修改,并且在当前作用域创建(复制)一份此变量。
    # nonlocal 可以在子级函数内部调用父级函数的变量,并且在自己的空间内也复制了一个同样的变量,并且可以进行修改
    def func():
        count = 0
        def inner():
            nonlocal count
            count += 1
            print(count)
            print(locals())
        inner()
        print(locals())
    func()
    # 通过locals 产看局部名称空间内变量,发酰两个函数空间内都存在count变量,并且都被修改
  9. 默认参数的坑

    # 当你的默认参数是不可变数据类型时,可以直接在传参时进行修改
    def func(a,b=False):
        print(a)
        print(b)
    func(1,True)
    
    # 当你的默认参数如果是可变的数据类型,你要小心了。
    def func(a,l=[]):
        l.append(a)
        return l
    print(func(1))  # [1,]
    print(func(2))  # [1,2,]
    print(func(3))  # [1,2,3,]
    # 当你这样传入参数时,原参数不是直接被替代,而是一直往列表里添加

    2.函数名的应用

  10. 函数名是一个特殊的变量。

    def func():
        print(666)
    print(func)  # func的指向地址 <function func at 0x00000000003F1EA0>
    # func 与变量一样,指向的是一个内存地址 
    # 1,函数名指向的是函数的内存地址,加上()就执行这个函数。
    # func() 这样才是执行函数的意思
  11. 函数名是一个变量。

    print(age3)
    def func():
        print(666)
    f1 = func
    f2 = f1
    f2()
    f1()
    # 函数名与变量命一样,可以直接进行赋值
  12. 函数名可以作为容器类类型的元素。

    def func1():
        print('in func1')
    def func2():
        print('in func2')
    def func3():
        print('in func3')
    l = [func1, func2, func3]
    for i in l:
        i()
    # 函数名可以放在列表等容器里充当元素,可以for循环执行函数
  13. 函数名可以作为函数的实参。

    def func1():
        print('in func1')
    def func2(argv):
        argv()
        print('in func2')
    func2(func1)
    # 函数名也可以作为实参来进行传参
  14. 函数名可以作为函数的返回值

    def func1():
        print('in func1')
    def func2(argv):
        print('in func2')
        return argv
    ret = func2(func1)  
    ret()
    # 函数名可以作为函数的返回值