10装饰器
# 装饰器定义?
# 装饰器就是对被装饰的对象(函数、类)进行重构,其可以在不改变原来对象的情况下,
# 调用对象时执行重构后的行为
#将欧美河南加上认证功能,并且加上vip等级
# account = {
# "is_authenticated":False,# 用户登录了就把这个改成True
# "username":"alex", # 假装这是DB里存的用户信息
# "password":"abc123" # 假装这是DB里存的用户信息
# }
# def login(func):
# def inner(*args,**kwargs): #后面因为加了vip等级认证,有了参数,但是不是所有专区都需要vip等级认证,所以可以用非固定参数
# 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 #注意函数无法修改全局变量,也就是无法修改account,但是可以修改里面的值
# func(*args,**kwargs) #可以直接调用外部函数
# else:
# print("wrong username or password!")
# else:
# print("用户已登录,验证通过...")
# func(*args,**kwargs) #当执行heman(4)虽然有调用func(*args,**kwargs) 去执行 henan(vip_level),但是不会立即执行,因为def inner(*args, **kwargs):还没未执行
# return inner #inner函数必须加,不能后面@login就会自动全部调用完,后面函数(比如america())调用就没有用
# def pay_money(func):
# def inner(*args, **kwargs):
# print('已经支付')
# func(*args, **kwargs)
# return inner
# def home():
# print("---首页----")
#
# @login # 装饰器 语法糖 上面还可以加装饰器 #等同于 america = login(america) 程序先执行这步,america就相当于inner 在执行america()
# def america():
# print ("----欧美vip专区----") #注意此处已经实现的功能的源代码不能修改了,这直接违反了软件开发中的一个原则“开放-封闭”原则
# def japan(): #封闭:已实现的功能代码块不应该被修改,开放:对现有功能的扩展开放
# print("----日韩专区----")
#
# @login # 等同于henan = login(henan) 先执行
# @pay_money #等同于henan = pay_money(henan) 后执行
# def henan(vip_level):
# if vip_level > 3:
# print('河南专区高级私密')
# else:
# print("----河南vip专区----")
# home()
# america() #此时的america就相当于inner,因此,此时调用的就是inner()函数
# henan(4) #根据封闭开放的原则,如果要扩展新功能,源代码调用方式也不能更改,如果一百个在之前调用了这个函数,如果修改了,是不是一百个人都要修改,是不是太麻烦
#函数也可以赋值
# def plus(n):
# return n+1
# calc = plus
# print(calc(10))
# def w1(func): #1
# def inner(): #7
# print("before w1") #10
# func() # 11
# print("after w1") #16
# return inner #8
# def w2(func): #2
# def inner(): #5
# print("before w2") #12
# func() #13
# print("after w2") #15
# return inner #6
# @w1 # 3 #裝飾器執行順序從下往上執行
# @w2 #4
# def test():
# print('test') #14
# test() #9 #函數調用還是從上網下執行
# def makeBold(fun): #1
# print('----a----') #8
# def inner(): #9
# print('----1----') #12
# return fun() #13
# return inner #10
# def makeItalic(fun): #2
# print('----b----') #5
# def inner(): #6
# print('----2----') #14
# return fun() #15
# return inner #7
# @makeBold #3
# @makeItalic #4
# def test():
# return 'hello python decorator'#16
# ret = test()#11
# print(ret) #17
#带参装饰器
# def outer(flag):
# def timer(func):
# def inner(*args, **kwargs):
# if flag:
# print('flag is active')
# func(*args, **kwargs)
# return
# return inner
# return timer
# @outer(True) #首先会执行outer(True),返回timer函 数,再和@相结合相当于work = timer(work)
# def work():
# print(111)
# work()
# from functools import wraps
# def wrapper(func):
# @wraps(func) #不改变使用装饰器原有函数的结构(如__name__, __doc__),func此时传入的为实参work,本来返回值inner赋值给work函数,但是因为wraps函数的原因
# def inner(): #保持了work = wrapper(work)不受影响
# print(func.__name__) # 此时输出的是func的实际参数work
# return func()
# return inner
# @wrapper
# def work():
# return 123
# print(work.__name__) #此时输入的是work的实际参数inner返回值
# work()
# def wrapper(flag):
# def timer(func):
# def inner(*args, **kwargs):
# nonlocal flag #要修改外部函数的变量则必须加上nonlocal进行声明修改才是有效的,否则程序会报错,
# if flag:
# print('flag is active')
# flag = func(*args, **kwargs)
# if not flag:
# print('flag is down')
# return flag
# return inner
# return timer
# @wrapper(True)
# def work():
# print(111)
# return False
# print(work())
# import re
# pattern = re.compile("o[gh]")
# p = pattern.fullmatch("dog")
# p2 = pattern.fullmatch("ohr")
# p3 = pattern.fullmatch("og")
# p4 = pattern.fullmatch("doggie", 1, 3)
# print(p, p2, p3.group(), p4.group(), sep='\n')
#fullmatch方法是完整匹配,所以前两次打印结果都为None,第三次完全匹配成功,输出结果 是og;变量p4的结果因为采用compile预编译模式对象调用fullmatch方法,参数1和3指的是对被匹配字 符串进行分片后再匹配,所以仍然返回og;print方法中设置了分隔符为换行符,所以输出结果不会显示 在一行内。
# import re
# ret = re.fullmatch('ab121', 'ab121')
# print(ret) #<_sre.SRE_Match object; span=(0, 5), match='ab121'>
# print(ret.group()) #ab121
# print(ret.groups()) #()
# ret1 = re.fullmatch('ab12', 'ab121') #<_sre.SRE_Match object; span=(0, 5), match='ab121'>
# print(ret)
# 正则表达式中,group()用来提出分组截获的字符串,()用来分组
# import re
# a = "123abc456"
# print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体
# print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1) #123
# print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2) #abc
# print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3) #456
# 1. 正则表达式中的三组括号把匹配结果分成三组
#
# group() 同group(0)就是匹配正则表达式整体结果
# group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。