day12闭包,装饰器

 一、闭包:内部函数引用了外部函数的变量.

# f1()
#闭包的定义
#内部的函数引用了外部函数的变量

# def f1(b):     #闭包的常用状态
#     def f2():
#         print(b)
#     return f2
#内部函数返回一个值到全局

# def f1(): #从内部函数返回一个值到全局
# b = 10
# def f2():
# return b
# return f2()
#
# print(f1())

 
def f1():
    a = 1
    def f2():
        def f3():
            print(a)
        f3()
        print('f3 : ',f3.__closure__)
    f2()
    print('f2 : ',f2.__closure__)

f1()   #__closure__ 用来查看是否是 闭包 cell就是调用的元素  三层的嵌套,f23调用了外层的元素,那么f2也是闭包了

从某个网页读取网页内容

from urllib.request import urlopen
# ret = urlopen('http://www.cnblogs.com/Eva-J/articles/7194277.html').read()
# print(ret)
def get_url(url):
    def read1():
        ret = urlopen(url).read()
        print(ret)
    return read1  

read_func = get_url('http://www.cnblogs.com/Eva-J/articles/7194277.html')  #结果是bytes类型。写入文件再打开就完成了转码
read_func()
read_func()

二、装饰器:

 

#装饰器的作用
# 在不改变函数的调用方式的情况下,给函数的前后添加新的功能

#从最简单的装饰器
def timmer(qqxing):   #timmer是装饰器的名字,传入的参数就是被装饰的函数
    def inner():      #在装饰器中需要定义一个内部函数
        print('调用func之前')
        qqxing()      #被装饰的函数,并且要执行
        print('调用func之后')
    return inner      #将内部函数的名字返回

@timmer   #语法糖  func = timmer(func)
def func():
    print('公司好老板好同事好')

# func()
# 完整的装饰-万能的装饰
def timmer(qqxing):   #timmer是装饰器的名字,传入的参数就是被装饰的函数
    def inner(*args,**kwargs):      #在装饰器中需要定义一个内部函数
        print('调用func之前')
        ret = qqxing(*args,**kwargs)      #被装饰的函数,并且要执行
        print('调用func之后')
        return ret
    return inner      #将内部函数的名字返回

@timmer   #语法糖  func = timmer(func)
def func(name):
    print('%s的公司好老板好同事好'%(name))
    return 1111111111

ret = func('俊杰')
print('result : %s'%ret)

#装饰器的固定结构
def wrapper(func):
    def inner(*args,**kwargs):
        """被装饰函数执行之前要添加的代码"""
        ret = func(*args,**kwargs)
        """被装饰函数执行之后要添加的代码"""
        return ret
    return inner

两个案例:1.一次认证,多次访问  2.将当前调用函数的日志记录在文件里

#概念
#开放封闭原则
#开放
    #对扩展是开放的

#封闭
    #对修改是封闭的

#装饰器:开放封闭原则
#一次认证多次免登陆
flag = False
def login(func):
    def inner(*args,**kwargs):
        global flag
        if flag == False:
            username = input('用户名:')
            password = input('密码:')
            if username == 'alex' and password == 'somebody':
                print('登录成功')
                flag = True
        if flag == True:
            ret = func(*args,**kwargs)
            return ret
    return inner

@login
def art():
    print('欢迎来到文章页')

@login
def dar():
    print('欢迎来到日记页')

#用装饰器实现,访问art或者dar函数,登陆一次之后,无需再次登录
# art()
# dar()

def log(func):
    def inner(*args,**kwargs):
        print('你要调用%s函数了'%func.__name__)
        ret = func(*args,**kwargs)
        return ret
    return inner

@log
def f1():
    print('f1')
@log
def f2():
    print('f2')

#日志
f1()
f2()

三层装饰器:

# def auth():
#     def auth2(func):
#         def wrapper(*args,**kwargs):
#             name=input("user: ")
#             pwd=input("pwd: ")
#
#             if True:
#                 if name == 'egon' and pwd == '123':
#                     print('login successful')
#                     res=func(*args,**kwargs)
#                     return res
#             else:
#                 print('ldap')
#         return wrapper
#     return auth2
# @auth()  # foo = auth(driver='file')(foo)  三层的话 语法糖那里要带上括号
# def foo(name):
#     print(name)
# foo('egon')

 

posted on 2017-11-04 15:54  心如沚水  阅读(130)  评论(0编辑  收藏  举报