zoukankan      html  css  js  c++  java
  • 装饰器和常用模块

    装饰器的概念

    内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了长裤后宝宝再也不冷了,装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效回到主题,装饰器在python的作用便是在不改变原有函数的情况下,增加原有函数的功能,装饰器的返回值也是一个函数。它经常用于有其他需求的场景,比如:插入日志、性能测试、事物处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

    口说无凭,上代码,先来段没用装饰器的代码:

    user_status = False #用户登录了就把这个改成True
     
    def login():
        _username = "alex" #假装这是DB里存的用户信息
        _password = "123456" #假装这是DB里存的用户信息
        global user_status
     
        if user_status == False:
            username = input("user:")
            password = input("pasword:")
     
            if username == _username and password == _password:
                print("welcome login....")
                user_status = True
            else:
                print("wrong username or password!")
        else:
            print("用户已登录,验证通过...")
     
    def home():
        print("---首页----")
     
    def america():
        login() #执行前加上验证
        print("----欧美专区----")
     
    def japan():
        print("----日韩专区----")
     
    def henan():
        login() #执行前加上验证
        print("----河南专区----")
     
    home()
    america()
    henan()
    

    程序的大意就是输入正确的用户名和密码后才能看到对应的版块,这里改动了源代码,就是在需要验证的版块出加了login函数,如果有很多版块的话,都得加上对应的login功能,工作量大,而且也改变了原有的代码结构,这直接违反了软件开发中的一个原则“开放-封闭”原则,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展。改进,看第二段代码

    既然上段代码违反了开发-封闭的原则,上次alex卖过一次关子,高阶函数什么时候回用到,现在就可以用到,例如,把america这个函数名传参至login,认证通过了就调用america函数,不就可以实现了不用改代码了,只是改变了调用方式而已。代码如下:

    user_status = False  # 用户登录了就把这个改成True
    def login(func):
        _username = "alex"  # 假装这是DB里存的用户信息
        _password = "123456"  # 假装这是DB里存的用户信息
        global user_status
    
        if user_status == False:
            username = input("user:")
            password = input("pasword:")
    
            if username == _username and password == _password:
                print("welcome login....")
                user_status = True
            else:
                print("wrong username or password!")
        else:
            # print("用户已登录,验证通过...")
            func()
    
    
    def home():
        print("---首页----")
    
    
    def america():
        login()  # 执行前加上验证
        print("----欧美专区----")
    
    
    def japan():
        print("----日韩专区----")
    
    
    def henan():
        login()  # 执行前加上验证
        print("----河南专区----")
    
    home()
    login(america)
    # henan()
    

    此时,虽然实现了需求,也不用改代码了,但是调用的方式变了,举个例子,一个银行的接口因为某种需求,改动了一个东西,如果合作伙伴需要用继续用这个功能的话,必须改动自己的调用方法,银行的合作伙伴多吧,不可能每个都去通知,再说别人也不想改代码啊,知不知道,产品经理说要改需求,程序员就想抽他,所以需要改动的是银行这边,实现既然实现需求,又不用改用任何代码和调用方式,代码如下:

    user_status = False
    def login(func):
        def inner():
            _username = "alex"
            _password = "123456"
            global user_status
            if user_status ==False:
                username = input("user:")
                password = input("password:")
                if username == _username and password == _password:
                    print("welcome login")
                    user_status = True
                else:
                    print("wrong username or password")
            if user_status == True:
                func()
        return inner
            # print("用户已登录,验证通过")
    def home():
        print("---首页---")
    
    def america():
        print("---欧美---")
    def japan():
        print("---日本---")
    def henan():
        print("---河南---")
    home()
    america = login(america)  #特别注意这里,可以print(america)看看结果
    # print(america)
    america()

    print效果如下:

    上述方法既可以实现不改动源代码的方式实现需求,也可以不改变调用方法,在python中,这就是装饰器的功能,又称语法糖。最终代码如下所示:

    user_status = False
    def login(func):
        def inner():
            _username = "alex"
            _password = "123456"
            global user_status
            if user_status ==False:
                username = input("user:")
                password = input("password:")
                if username == _username and password == _password:
                    print("welcome login")
                    user_status = True
                else:
                    print("wrong username or password")
            if user_status == True:
                func()
        return inner
            # print("用户已登录,验证通过")
    def home():
        print("---首页---")
    @login   #需要加上验证就在其函数上面添加@login
    def america():
        print("---欧美---")
    def japan():
        print("---日本---")
    def henan():
        print("---河南---")
    home()
    # america = login(america)  #特别注意这里,可以print(america)看看结果
    # print(america)
    america()

     os模块常用用法

    import os,sys
    
    #程序主目录文件
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    #添加环境变量
    sys.path.insert(0,BASE_DIR)
    
    # print(os.path.join())
    print(BASE_DIR)
    print(os.path.dirname(__file__))
    print(os.path.abspath(__file__))
    print(os.path.dirname(os.path.abspath(__file__)))
    
    #拼接路径的时候用的
    print(os.path.join("I","am","huihuang"))
    

     运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/os模块相关属性.py
    D:python开发代码Python之路作业
    D:/python开发代码/Python之路/作业/day8
    D:python开发代码Python之路作业day8os模块相关属性.py
    D:python开发代码Python之路作业day8
    Iamhuihuang
    
    Process finished with exit code 0
    

      

  • 相关阅读:
    java 继承(下)
    java继承
    java代码封装与编译
    使用Access-Control-Allow-Origin解决跨域
    java (基本语法)
    ZendStudio如何汉化
    如何让数据库在每天的某一个时刻自动执行某一个存储过程或者某一个sql语句
    百度地图不用密匙也可以使用
    .net在当前日期的基础上加一天
    当你的IIS需要运行ASP网站时,需要这样配置下你的IIS
  • 原文地址:https://www.cnblogs.com/uglyliu/p/6045796.html
Copyright © 2011-2022 走看看