002---函数进阶

函数进阶

名称空间

  • 概念:name space,顾明思议就是存放名字的地方。
  • 举例:变量x=1,变量值1存在内存中,那变量名存哪呢?名称空间就是存放变量名与变量值绑定关系的地方
  • 分类:
    • locals:函数内的名称空间,包括局部变量和形参
    • globals:全局变量,函数定义所在模块的名称空间。
    • builtins:内置模块的名称空间
  • 名称空间绝定变量的作用域
    • 全局作用域:全局存活,全局有效
    • 局部作用域:临时存活,局部有效
  • 查看作用域方法:locals()、globals()
name = '子牙'
age = 22


def inner():
    name = '子牙1'
    print('局部变量:', locals())

    def outer():
        def func():
            # name = '子牙3'
            print('局部变量:', locals())
            # print(name)  # 作用域向上查找,如果没有引用name,局部变量就是空{},一旦引用就是{'name': '子牙1'}

        func()

    outer()


inner()
print('全局变量:', globals())

闭包

  • 函数定义和函数表达式在另一个函数的里面(函数嵌套),而且内部函数可以访问外部函数所声明的局部变量,参数。当内部函数被外部函数之外调用的时候,就会形成闭包。
  • 闭包的意义:返回函数对象,使得该函数无论在何处调用,优先使用自己外层包裹的作用域。

装饰器

  • 软件开发原则:

    • 对外开放扩展:对现有功能进行扩展
    • 对内封闭不修改:以实现的功能代码块不应该被修改
  • 装饰器:闭包 + 高阶函数 + 嵌套

  • 满足条件:

    • 不修改原来函数的代码
    • 不修改原来函数的调用方式
  • 代码示例(无参)

def f(f1):
    print('装饰前')  # 虽然没括号调用,其实已经调用了

    def inner(*args):  # 其他函数调用,所以不用限制参数,用不固定参数
        print('装饰后')
        print('带来的参数', args)
        res = f1(*args)
        print('被装饰函数的执行结果:',res)
        return res

    return inner


@f
def f1(name):
    return 1111


print('返回值',f1('name'))  # -->f1 = f(f1) = inner
  • 代码示例(带参)
# 带参数的装饰器 外面再套一层
def f(type):
    print('带参装饰器',type)
    def outer(f1):
        def inner(*args):
            print('装饰后')
            print('带来的参数', args)
            res = f1(*args)
            print('被装饰函数的执行结果:', res)
            return res

        return inner
    return outer

@f('qq')                    #先执行f('qq')得到outer  然后@outer
def f1(name):
    return 1111

print('返回结果', f1('name'))

  • 扩展
# 两个装饰器修饰同一个应用
def w1(func):
    def inner():
        print("before w1")
        func()
        print("after w1")
    return inner
def w2(func):
    def inner():
        print("before w2")
        func()
        print("after w2")
    return inner

@w1
@w2
def test():
    print('test')
test()

# 第一个装饰 w1
# test = w1(test)  test = inner
# test()-->inner()-->func()--
# print('before w1')

# 第二个装饰 w2
# test = w2(inner) test = inner()
# test()--inner()--func()
# print('before w2')
# print('test')
# print('after w2')

# 第二个装饰器结束
# print('after w1')
  • 装饰器修复技术
from functools import wraps


def deco(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)

    return wrapper


@deco
def index():
    """
    装饰器修复技术
    :return:
    """
    print('from index')


index()

print(index.__name__)  # wrapper  加了装饰器修复技术之后,会打印index
posted @ 2019-01-30 09:33  爬呀爬Xjm  阅读(113)  评论(0编辑  收藏  举报