装饰器和常用模块

装饰器的概念

内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了长裤后宝宝再也不冷了,装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效回到主题,装饰器在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.5\python.exe D:/python开发代码/Python之路/作业/day8/os模块相关属性.py
D:\python开发代码\Python之路\作业
D:/python开发代码/Python之路/作业/day8
D:\python开发代码\Python之路\作业\day8\os模块相关属性.py
D:\python开发代码\Python之路\作业\day8
I\am\huihuang

Process finished with exit code 0

  

 

posted @ 2016-11-09 09:52  梦轻尘  阅读(214)  评论(0编辑  收藏  举报