• py-函数进阶


    名称空间

      又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方

    名称空间共3种,分别如下

    locals: 是函数内的名称空间,包括局部变量和形参

    globals: 全局变量,函数定义所在模块的名字空间

    builtins: 内置模块的名字空间

    不同变量的作用域不同就是由这个变量所在的命名空间决定的。

    作用域即范围

    全局范围:全局存活,全局有效

    局部范围:临时存活,局部有效

    查看作用域方法 globals(),locals()

    问题:在inner()里的打印的n的值是多少?

    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__

    locals 是函数内的名字空间,包括局部变量和形参

    enclosing 外部嵌套函数的名字空间

    globals 全局变量,函数定义所在模块的名字空间

    builtins 内置模块的名字空间

     

    闭包

      关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响

    def outer():
        name = 'alex'
        def inner():
            print("在inner里打印外层函数的变量",name)
        return inner
    f = outer()
    f()

    有权访问另一个函数作用域内变量的函数都是闭包

      闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    列表生成式

    >>> [x for x in range(1,11) ]     
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> [x+1 for x in range(1,11) ] [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    >>> [i if i<5 else i*i for i in range(1,11)] [1, 2, 3, 4, 25, 36, 49, 64, 81, 100]

    生成器

    >>> def fib(num):
        n,a,b = 0,0,1
        while n<num:
            yield b           #冻结,并返回b的值。可以返回状态
            a,b = b,a+b
            n += 1
        return 'done'
         
    >>> fib(10)
    <generator object fib at 0x0000023C08453AF0>
    >>> a= fib(10)    
    >>> a   
    <generator object fib at 0x0000023C08453BF8>
    >>> next(a)       
    1
    >>> next(a)      
    1
    >>> next(a)
    2
    >>> next(a)
    3
    >>> next(a)        
    5
    View Code
    range也是一个生成器,和py2的xrange相同
    
    py2
    range = list
    xrange = 生成器
    
    
    py3
    range = 生成器
    xrange 没有

    生成器创建方式

    1.列表生成式()
    2.函数           yield
    
    函数内部任何一个部位,想要冻结返回就用生成器
    
    函数.__next__()
    有 yield 再有 return
    包子机
    import time
    def consumer(name):
        print("%s 准备吃包子啦!" %name)
        while True:
            baozi = yield
            print(baozi)
            print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
    
    
    def producer(name):
    
        c = consumer('A')
        c2 = consumer('B')
        c.__next__()        #由于yield,c会阻塞住,直到返回值
        c2.__next__()
        print("老子开始准备做包子啦!")
        for i in range(10):
            time.sleep(1)
            print("做了2个包子!")
            c.send(i)       # yield 接受到值,于是开始走下面的print语句
            c2.send(i)
                            # 最后不再给yield 传值,
    producer('root')

    装饰器

    带参数装饰器
    #_*_coding:utf-8_*_
    user_status = False #用户登录了就把这个改成True
    
    def login(auth_type): #把要执行的模块从这里传进来
        def auth(func):
            def inner(*args,**kwargs):#再定义一层函数
                if auth_type == "qq":
                    _username = "alex" #假装这是DB里存的用户信息
                    _password = "abc!23" #假装这是DB里存的用户信息
                    global user_status
    
                    if user_status == False:
                        username = input("user:")
                        password = input("pasword:")
    
                        if username == _username and password == _password:
                            print("welcome login....")
                            user_status = True
                        else:
                            print("wrong username or password!")
    
                    if user_status == True:
                        return func(*args,**kwargs) # 看这里看这里,只要验证通过了,就调用相应功能
                else:
                    print("only support qq ")
            return inner #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数
    
        return auth
    
    def home():
        print("---首页----")
    
    @login('qq')
    def america():
        #login() #执行前加上验证
        print("----欧美专区----")
    
    def japan():
        print("----日韩专区----")
    
    @login('weibo')
    def henan(style):
        '''
        :param style: 喜欢看什么类型的,就传进来
        :return:
        '''
        #login() #执行前加上验证
        print("----河南专区----")
    
    home()
    # america = login(america) #你在这里相当于把america这个函数替换了
    #henan = login(henan)
    
    # #那用户调用时依然写
    america()
    
    # henan("3p")
    View Code

    。。。未完

  • 相关阅读:
    Centos系统下载
    Centos7 安装 docker
    Centos6 安装 docker
    yum提示Another app is currently holding the yum lock; waiting for it to exit...
    Oracle 时间字段显示不正确,类型错误
    Android 报错:error: too many padding sections on bottom border
    vs文件上传失败--超过最大字符限制
    ButterKnife 牛油刀使用
    VS项目发布到本地IIS
    Visual Studio无法调试
  • 原文地址:https://www.cnblogs.com/wenyule/p/9044152.html
Copyright © 2020-2023  润新知