装饰器和常用模块
装饰器的概念
内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了长裤后宝宝再也不冷了,装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效回到主题,装饰器在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