函数进阶---作用域、闭包、装饰器

名称空间

名称空间指存放名字的地方
名称空间分为三种

  • locals:函数内部的名称空间,包括局部变量与形参
  • globals:全局变量,函数模块定义所在模块的空间
  • builtins 内置模块的名称空间
    不同变量的作用域不同就是由这个变量的所在变名空间决定的
    作用域:
    全局范围:全局存活,在全局生效
    局部范围:局部存活,在局部生效
    查看作用域的方法:locals(),globals()
    名称空间的查找顺序
    LEGB查找顺序:locals-->enclosing function-->globals-->builtins
  • locals:指局部名称空间
  • enclosing function:指外部嵌套函数的名称空间
  • globals:全局变量,函数模块定义所在的名称空间
  • builtins:内置模块的名称空间

闭包

闭包是指内部函数包含对外部作用域而非全局作用域的引用,即:A函数里再定义一个b函数(嵌套函数)而B函数里调了A函数的变量,而A函数返回值是B函数的引用,这样就构成了闭包

def fun():
    name = 'ab'
    def fun1():
        print('fun1',name)
    return fun1
a = fun()
a()

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

装饰器

什么是装饰器?

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:

  • 不修改被装饰对象的源代码
  • 不修改被装饰对象的调用方式
    装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

程序员应该尊守封闭,开发原则!

  • 封闭:已实现的功能代码块不应该被修改
  • 开放:对现有功能的扩展开放

代码:

flag = False

def login(fun):
    def ineer(*args,**kwargs):
        username = 'alex'
        password = '123'
        global flag
        if flag == False:
            _username = input('user:').strip()
            _passwd = input('passwd:').strip()

            if _username == username and _passwd == password:
                print('登陆成功')
                flag = True
            else:
                print('登陆失败')
        if flag == True:
            return fun(*args,**kwargs)
    return ineer

def home():
    print("---首页----")

@login
def america():
    #login() #执行前加上验证
    print('用户已登陆,不需要验证')
    print("----欧美专区----")

def japan():
    print("----日韩专区----")

@login #想当于henan = login(henan)
def henan(style):
    '''
    :param style: 喜欢看什么类型的,就传进来
    :return:
    '''
    #login() #执行前加上验证
    print("----河南专区----")
henan('3p') #实际调用的是inner函数
america()
posted @ 2018-05-18 18:27  游走在边缘的人  阅读(91)  评论(0编辑  收藏  举报