zoukankan      html  css  js  c++  java
  • ~~函数基础(六):装饰器~~

    进击のpython

    *****

    装饰器


    知道京东吧(不知道?那你知道淘宝,蘑菇街吧)

    我们身为用户,在进入界面的时候

    首先会提示我们登陆是吧

    当我们登陆的时候,接下来的所有操作就不用再验证身份了

    否则,一到收藏啊,关注啊,就需要我们重新登陆

    那我们可不可以做一个这个呢??

    没有数据库,我们模拟一个数据库,懂我意思吧!


    DB = {
        "login": False,
        "user_name": "poddy",
        "password": "123546"}
    
    
    def login():
        if DB["login"] == False:
            usr = input("请输入用户名:")
            psd = input("请输入密码:")
            if usr == "poddy" and psd == "123546":
                print("登陆成功!")
                DB["login"] = True
            else:
                print("登录失败!")
                login()
    
    
    
    def meizhuang():
        login(meizhuang)
        print("美妆专区")
    
    
    def qinzi():
        login(qinzi)
        print("亲子专区")
    
    
    def dianzi():
        login()
        print("电子专区")
    
    dianzi()
    

    这样,就完成了需求了

    但是!!!!!!!!!!!!!!!!!!!!!!!

    你改变了原来的写好的函数模块,你把每个模块都加上了login()函数

    这样是不符合“开放-封闭”原则的(第一个原则!)

    就是我现在实现的代码块(def里面包着的)你不能给我动

    但是你可以给我加功能!


    那就想到了函数的嵌套,将上一个函数当作参数传过来就完事了呗!

    想的很好!于是进阶版来了!

    DB = {
        "login": False,
        "user_name": "poddy",
        "password": "123546"}
    
    
    def login(func):
        if DB["login"] == False:
            usr = input("请输入用户名:")
            psd = input("请输入密码:")
            if usr == "poddy" and psd == "123546":
                print("登陆成功!")
                DB["login"] = True
                func()
            else:
                print("登录失败!")
                login(func)
        # if DB["login"] == True:
        #     func()
    
    
    def meizhuang():
        print("美妆专区")
    
    
    def qinzi():
        print("亲子专区")
    
    
    def dianzi():
        print("电子专区")
    
    
    login(dianzi)
    

    OKOK,大功告成!

    但是,还不行!!!!!!!!!!!!!!!!!!!!!!!!

    你想想熬,你写的是函数是吧

    原先调用函数是介个亚子

    dianzi()
    

    现在调用呢?就变成了这个亚子

    login(dianzi)
    

    一个人两个人好说,啊,改变一下调用方法

    那要是很多人呢?你确定你还能活着出去?

    调用方法也不能变!代码块也不能变!那要怎么做呢?


    记得在匿名函数那提过,给匿名函数取名然后调用的问题

    匿名函数不是函数嘛?那就是说明函数也是可以被命名的

    这么解释有问题吗?

    那我们是不是可以这么考虑

    dianzi = login(dianzi)
    dianzi()
    

    执行一下,报错了!

    为啥呢?仔细看一下,在执行 login(diazi) 的时候,按照代码逻辑,最后执行的是dianzi()

    现在你将 login(diazi) 重命名为 dianzi , 然后执行dianzi()

    那不就相当于你执行了 login(diazi)() 四舍五入最后你执行的就是 dianzi()()

    dianzi()()??? 你见过这玩仍????


    • 装饰器

      这个问题是怎么解决的呢?

      DB = {
          "login": False,
          "user_name": "poddy",
          "password": "123546"}
      
      
      def login(func):
          def inner():
              if DB["login"] == False:
                  usr = input("请输入用户名:")
                  psd = input("请输入密码:")
                  if usr == "poddy" and psd == "123546":
                      print("登陆成功!")
                      DB["login"] = True
                      func()
                  else:
                      print("登录失败!")
                      login(func)
      
          return inner
      
      
      def meizhuang():
          print("美妆专区")
      
      
      def qinzi():
          print("亲子专区")
      
      
      def dianzi():
          print("电子专区")
      
      
      dianzi = login(dianzi)
      
      dianzi()
      

      来吧,开始分析!

      通过闭包(野生程序员和科班程序员区别)和高阶函数,达到了效果

      而这个操作,就是装饰器

      当然,还有更简单的写法!

      DB = {
          "login": False,
          "user_name": "poddy",
          "password": "123546"}
      
      
      def login(func):
          def inner():
              if DB["login"] == False:
                  usr = input("请输入用户名:")
                  psd = input("请输入密码:")
                  if usr == "poddy" and psd == "123546":
                      print("登陆成功!")
                      DB["login"] = True
                      func()
                  else:
                      print("登录失败!")
                      login(func)
      
          return inner
      
      
      @login
      def meizhuang():
          print("美妆专区")
      
      
      @login
      def qinzi():
          print("亲子专区")
      
      
      @login
      def dianzi():
          print("电子专区")
      
      
      dianzi()
      

    • 进阶

      我又有需求了!(这个人就是神经病!)

      那我想这样,我要是等级高,在电子区我就可以打折

      ┗|`O′|┛ 嗷~~简单,加个参数嘛!

      DB = {
          "login": False,
          "user_name": "poddy",
          "password": "123546"}
      
      
      def login(func):
          def inner():
              if DB["login"] == False:
                  usr = input("请输入用户名:")
                  psd = input("请输入密码:")
                  if usr == "poddy" and psd == "123546":
                      print("登陆成功!")
                      DB["login"] = True
                      func()
                  else:
                      print("登录失败!")
                      login(func)
      
          return inner
      
      
      @login
      def meizhuang():
          print("美妆专区")
      
      
      @login
      def qinzi():
          print("亲子专区")
      
      
      @login
      def dianzi(vip):
          if vip >2:
              print("你可以打折")
          else:
              print("电子专区")
      
      
      dianzi(4)
      

      执行!报错!

      他说什么?inner() 里没有参数,但是我放进去了一个参数

      inner()?不应该是 dianzi() ?

      奥,才想起来,现在的 dianzi() 其实就是 inner()

      所以报错的是inner()

      缺参数是吧,那就加上被!

      DB = {
          "login": False,
          "user_name": "poddy",
          "password": "123546"}
      
      
      def login(func):
          def inner(vip):
              if DB["login"] == False:
                  usr = input("请输入用户名:")
                  psd = input("请输入密码:")
                  if usr == "poddy" and psd == "123546":
                      print("登陆成功!")
                      DB["login"] = True
                      func(vip)
                  else:
                      print("登录失败!")
                      login(func)
      
          return inner
      
      
      @login
      def meizhuang():
          print("美妆专区")
      
      
      @login
      def qinzi():
          print("亲子专区")
      
      
      @login
      def dianzi(vip):
          if vip >2:
              print("你可以打折")
          else:
              print("电子专区")
      
      
      dianzi(4)
      

      执行!成功!

      完事了?并没有,当我加上一条这样的语句的时候

      meizhuang()
      

      这个错误又出现了!

      那我这个“美妆”版块,也不存在打折啊,我还能强行加个参数??

      想到了哪个知识点?对!参数里的非固定参数

      将代码修改一下:

      DB = {
          "login": False,
          "user_name": "poddy",
          "password": "123546"}
      
      
      def login(func):
          def inner(*args,**kwargs):
              if DB["login"] == False:
                  usr = input("请输入用户名:")
                  psd = input("请输入密码:")
                  if usr == "poddy" and psd == "123546":
                      print("登陆成功!")
                      DB["login"] = True
                      func(*args,**kwargs)
                  else:
                      print("登录失败!")
                      login(func)
      
          return inner
      
      
      @login
      def meizhuang():
          print("美妆专区")
      
      
      @login
      def qinzi():
          print("亲子专区")
      
      
      @login
      def dianzi(vip):
          if vip >2:
              print("你可以打折")
          else:
              print("电子专区")
      
      
      dianzi(4)
      meizhuang()
      

      大功告成!装饰器其实就是这样的结构!!这个知识点很重要!!!

      最后再来个小题试试吧

      我想在电子专区加一个支付模块(print(“支付成功”)意思意思就行)

      怎么写呢?????????????????????????


    *十分重要*
    *值得深究*
  • 相关阅读:
    Mac版sublime text右键open in browser 不能识别中文名解决办法
    python 内置函数
    python 迭代器 生成器 列表推导式和生成器表达式
    python 闭包
    python 练习题
    python 打印扑克牌练习题
    python 函数 可变数据类型默认值
    python min() ,max()
    python 九九乘法表
    函数的进阶
  • 原文地址:https://www.cnblogs.com/jevious/p/11141776.html
Copyright © 2011-2022 走看看