python基础 -19- 函数(闭包,装饰器)

闭包

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

def outer():
    name = 'alex'
    def inner():
        print("在inner里打印外层函数的变量",name)
    return inner # 注意这里只是返回inner的内存地址,并未执行


f = outer() # .inner at 0x1027621e0>
f()  # 相当于执行的是inner()

 输出

在inner里打印外层函数的变量 alex

 注意此时outer已经执行完毕,正常情况下outer里的内存都已经释放了,但此时由于闭包的存在,我们却还可以调用inner, 并且inner内部还调用了上一层outer里的name变量。这种粘粘糊糊的现象就是闭包。

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


装饰器

account = {
    "is_authenticated":False,# 用户登录了就把这个改成True
    "username":"admin", # 假装这是DB里存的用户信息
    "password":"123456" # 假装这是DB里存的用户信息
}
def login(func):
    def inner(*args, **kwargs):
        if account["is_authenticated"] is False:
            username = input("user:")
            password = input("pasword:")
            if username == account["username"] and password == account["password"]:
                print("welcome login....")
                account["is_authenticated"] = True
            else:
                print("wrong username or password!")
        if account["is_authenticated"] is True:  # 主要改了这
            func(*args, **kwargs)  # 认证成功了就执行传入进来的函数
    return inner

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

def america():
    print("----欧美专区----")

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

def henan(*args, **kwargs):
    print("----河南专区----")
    print(kwargs["note"])

home()

america = login(america) # 需要验证就调用 login,把需要验证的功能 当做一个参数传给login
henan = login(henan)
america()
henan(note="什么玩意呀(滑稽)~~~")

japan("日韩的好呀~~~")

 输出

---首页----
user:admin
pasword:123456
welcome login....
----欧美专区----
----河南专区----
什么玩意呀(滑稽)~~~
----日韩专区----
日韩的好呀~~~

 想实现一开始你写的america = login(america)不触发你真正的america函数的执行,只需要在这个login里面再定义一层函数,第一次调用america = login(america)只调用到外层login,这个login虽然会执行,但不会触发认证了,因为认证的所有代码被封装在login里层的新定义 的函数里了,login只返回 里层函数的函数名,这样下次再执行america()时, 就会调用里层函数啦。。。

@login注解就相当于一个语法糖吧,我们并不需要显示的去调用装饰方法。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值