zoukankan      html  css  js  c++  java
  • python--函数、参数、名称空间与作用域、匿名函数、内置函数、闭包

    python函数

    函数定义

    def welcome():
        print('hello world!!')
    welcome()    #函数调用
    
    ...运行结果
    
    hello world!!
    

    函数定义和编写原则:

    1. 尽量一个动作一个函数,以减少函数之间的耦合性;

    函数传参

    实参和形参

    位置实参:函数调用时,每个形参都有一个实参(值)与之关联对应,最简单的关联方式是基于实参的顺序。

    def num (a,b):  #a,b为形参
        print(a)
        print(b)
        print(a +b)
    num(1,2)  #1,2为实参
    
    ...运行结果
    
    1
    2
    3
    

    关键字实参:给函数以名称-值对的方式关联形参。

    def num (a,b):
        print(a)
        print(b)
        print(a +b)
    num(b=1,a=2)
    
    ...运行结果
    
    2
    1
    3
    

    默认值:编写函数时可以给形参指定默认值,如果没有实参与之关联实用默认值,有实参与之关联,使用实参值。

    def num (a,b=1):
        print(a)
        print(b)
        print(a +b)
    num(1,)
    
    ...运行结果
    
    1
    1
    2
    
    def num (a,b=1):
        print(a)
        print(b)
        print(a +b)
    num(1,2)
    
    ...运行结果
    
    1
    2
    3
    

    不定长参数(*args )

    在定义函数时可以在函数的形参前头加一个*,这样的形参可以获取到所有的实参,它会将所有的实参保存到一个元组中;即*a会接受所有的位置实参,并将这些实参统一保存到一个元组中。

    *a 不一定必须放在最后面,但是*a后面的形参传参必须用关键字参数
    *a 只能接受位置实参,不能接受关键字实参

    实例:

    def name_list(company,*names):
        print('%s公司人员名单:'%company)
        for name in names:
            print(name)
    name_list('老k天下','张三','李四','王二')
    
    ...................................运行结果
    
    老k天下公司人员名单:
    张三
    李四
    王二
    

    讲解:

    上述函数python将收到的第一个值传给company,并将其他所有值储存在元组names中。

    不定长参数(**kwargs)

    **形参可以接受其他关键字参数,它会将这些参数统一保存到一个字典中,字典的key就是参数的名字,字典的value就是参数的值
    **形参只能有一个,且只能写在所有形参的最后面

    实例:

    def build_file(name,**name_info):
        namefile = {}
        namefile['name'] = name
        for key,value in name_info.items():
            namefile[key] = value
        return namefile
    
    user_file = build_file('sb',
            age = 28,
            high = 180)
    print(user_file)
    
    .....................................运行结果
    
    {'name': 'sb', 'age': 28, 'high': 180}
    

    讲解:

    形参name_info中的两个让python创建一个名为name_info的空字典,并将收到的所有名称-值都封装在这个字典中。

    参数的解包(拆包)

    def fn4(a,b,c):
        print('a =',a)
        print('b =',b)
        print('c =',c)
    
    # 创建一个元组
    t = (10,20,30)
    
    # 传递实参时,也可以在序列类型的参数前添加星号,这样他会自动将序列中的元素依次作为参数传递
    # 这里要求序列中元素的个数必须和形参的个数的一致
    # fn4(*t)    
    
    # 创建一个字典
    d = {'a':100,'b':200,'c':300}
    # 通过 **来对一个字典进行解包操作
    fn4(**d)
    

    return

    函数返回值

    比较实例1:

    def num (a=1,b=2):
        print(a +b)
    print(num())
    
    ...运行结果
    
    3
    None
    

    比较实例2:

    def num (a=1,b=2):
        print(a +b)
        return a+b
    print(num())
    
    ...运行结果
    
    3
    3
    

    实例

    统计cpu memory disk 使用情况:

    import psutil
    
    def cpu():
        cpu = psutil.cpu_percent(1)
        return {'cpu_percent': cpu}
    
    def mem():
        mem_total = psutil.virtual_memory()[0]
        mem_percent = psutil.virtual_memory()[2]
        return {'mem_total':int(mem_total/1024/1024),'mem_percent': mem_percent}
    
    def disk():
        disk_total = psutil.disk_usage('c:')[0]
        disk_percent = psutil.disk_usage('c:')[3]
        return {'disk_total': int(disk_total/1024/1024/1024), 'disk_percent': disk_percent}
    
    def main():
        info = {}
        info.update(cpu())
        info.update(mem())
        info.update(disk())
    
        msg = '''
        cpu使用率:%s%%
        内存使用率:%s%%
        硬盘使用率:%s%%
        ==============
        内存总大小:%sM
        硬盘总打小:%sG
        ''' % (info['cpu_percent'],info['mem_percent'],info['disk_percent'],info['mem_total'],info['disk_total'])
        return msg
    
    if __name__ == '__main__':
        print(main())
    
    .........................................................运行结果
    
        cpu使用率:7.8%
        内存使用率:42.3%
        硬盘使用率:30.4%
        ==============
        内存总大小:8070M
        硬盘总打小:69G
    

    拓展:名称空间与作用域

    命名空间指的是变量存储的位置,每一个变量都需要存储到指定的命名空间当中
    每一个作用域都会有一个它对应的命名空间
    全局命名空间,用来保存全局变量。函数命名空间用来保存函数中的变量
    命名空间实际上就是一个字典,是一个专门用来存储变量的字典
    内置名称空间:(python启动时就有)python解释器内置的名字,print,max,min
    全局名称空间:(执行python文件时启动)定投定义的变量
    局部名称空间:(调用函数时启动,调用结束失效)函数内部定义的变量
    加载顺序:内置--->全局--->局部
    访问顺序:局部--->全局--->内置

    def func1():
        def func2():
            def func3():
                print(print)
            func3()
        func2()
    func1()
    -------------------------------------------------------------------------------------------------
    # locals()用来获取当前作用域的命名空间
    # 如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间
    # 返回的是一个字典
    scope = locals() # 当前命名空间
    print(type(scope))
    # print(a)
    # print(scope['a'])
    # 向scope中添加一个key-value
    scope['c'] = 1000 # 向字典中添加key-value就相当于在全局中创建了一个变量(一般不建议这么做)
    # print(c)
    
    def fn4():
        a = 10
        # scope = locals() # 在函数内部调用locals()会获取到函数的命名空间
        # scope['b'] = 20 # 可以通过scope来操作函数的命名空间,但是也是不建议这么做
    
        # globals() 函数可以用来在任意位置获取全局命名空间
        global_scope = globals()
        # print(global_scope['a'])
        global_scope['a'] = 30
        # print(scope)
    
    fn4() 
    

    在Python中一共有两种作用域
    全局作用域

    • 全局作用域在程序执行时创建,在程序执行结束时销毁
    • 所有函数以外的区域都是全局作用域
    • 在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问

    函数作用域

    • 函数作用域在函数调用时创建,在调用结束时销毁
    • 函数每调用一次就会产生一个新的函数作用域
    • 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问

    变量的查找

    • 当我们使用变量时,会优先在当前作用域中寻找该变量,如果有则使用,
      如果没有则继续去上一级作用域中寻找,如果有则使用,
      如果依然没有则继续去上一级作用域中寻找,以此类推
      直到找到全局作用域,依然没有找到,则会抛出异常
      NameError: name 'a' is not defined
    def fn2():
        def fn3():
            print('fn3中:','a =',a)
        fn3()
    
    # fn2()    
    
    a = 20
    
    def fn3():
        # a = 10 # 在函数中为变量赋值时,默认都是为局部变量赋值
        # 如果希望在函数内部修改全局变量,则需要使用global关键字,来声明变量
        global a # 声明在函数内部的使用a是全局变量,此时再去修改a时,就是在修改全局的a
        a = 10 # 修改全局变量
        print('函数内部:','a =',a)
    
    # fn3()
    # print('函数外部:','a =',a)
    

    拓展:匿名函数:lambda

    lambda函数:自带return

    #语法: lambda 参数:返回值
    
    res=(lambda x,y:x+y)(1,2)
    print(res)
    

    拓展:内置函数:max, sorted, map, filter

    powerinfo = {
        '大娃': 40000,
        '二娃':30000,
        '三娃': 25000,
        '蛤蟆精': 2000
    }
    

    max:取最大

    def func(k):
        return powerinfo[k]
    res = max(powerinfo,key=lambda k: powerinfo[k])
    print(res)
    

    sorted:排序

    # sorted()为内置函数,可以对任意序列进行排序
    # sorted()并不影响原来的对象,而是返回一个新的对象
    # sorted()可以接受一个关键字参数 key
    #     key需要一个函数作为参数
    
    res = sorted(powerinfo,key=lambda k:powerinfo[k])
    print(res)
    

    map:映射

    names = ['大娃', '二娃', '三娃']
    res = map(lambda i: i % name,names)
    #或
    res = map(lambda name: '%s_会武功' % name,names)
    print(list(res))
    

    zip:拉链

    l1 = [1,2,3]
    l2 = ['a','b','c','d']
    res = zip(l1,l2)
    print(list(res))
    

    filter:过滤

    names = ['大娃_会武功', '二娃_会武功', '三娃_会武功','蛤蟆精']
    
    res = filter(lambda name: name.endswith('会武功'),names)
    print(list(res))
    

    拓展:闭包

    当有一些见不得人的东西需要隐藏的时候(需要设定变量,只有本函数可以调用),我们可以用到闭包。

    闭包的形成条件:

    • 函数嵌套
    • 将内部函数作为返回值返回
    • 内部函数必须要使用到外部函数的变量
    def make_averager():
        #创建一个表用来保存数
        nums = []
        #创建一个函数用来计算平均值
        def averager(int(n)):
            nums.append(n)
            return sun(nums)/len(nums)
        return averager()
    
    print(make_averager(10))
    print(make_averager(10))
    print(make_averager(10))
    nums = []  #对求名平均值没有影响,因为用了闭包,命名空间不同,不是同一个对象
    print(make_averager(10))
    

  • 相关阅读:
    批量改主机名报错:Address 192.168.43.117 maps to bogon, but this does not map back to the address
    ssh远程登录连接慢的解决方法
    expect脚本远程登录、远程执行命令和脚本传参简单用法
    将集群WEB节点静态数据迁移到共享存储器(LNMP环境)
    LAMP环境搭建之编译安装指南(php-5.3.27.tar.gz)
    手把手教你设置MongoDB密码
    手把手教你在Linux系统下安装MongoDB
    手把手教你在Linux系统下安装MySQL
    在Linux下使用rm -rf /*后会怎样?
    Failed to configure a DataSource 'url' attribute问题解决
  • 原文地址:https://www.cnblogs.com/du-z/p/11038551.html
Copyright © 2011-2022 走看看