Python基础 ( 七 ) —— 装饰器

#装饰器

#定义:用于修饰函数的函数(给函数添加新功能)

原则:不改变函数的调用方式

   不改变函数源代码

装饰器=高阶函数(函数的参数或返回值为函数) + 函数嵌套 + 闭包

#小补充

1.获取运行时间

import time
start = time.time()
time.sleep(1)
end = time.time()
print(end-start)

2.一种不用索引取列表首位的方法(解压序列)

l=[1,2,3,4,5,6]
(a,*_,c)= l            #这里的_就是个变量名,用其他字符串也可以
print(c)                 #输出最后一个数
print(_)                #输出去除首尾的中间数

 

或者可以取任意位置的值

l=[1,2,3,4,5,6]
(a,b,*_,c,d)= l
print(a,b,c,d)
print(_)

3.交换变量的值(简便)

a,b=1,2
a,b=b,a    #其实用了元祖的概念做了以下步骤 a,b = (a,b) = b,a
print(a)

 

 

 

#装饰器的前身——满足装饰器原则,但多运行了一次原函数

#只使用了高阶函数

import time
def object():
    time.sleep(1)
    print('对象函数运行成功')
def processor(fuc):
    start_time = time.time()
    fuc()
    end_time = time.time()
    print('函数运行时间:%s' %(end_time-start_time))
    return fuc
object = processor(object)
object()

 #函数嵌套——函数里面定义函数

 

def father(name):
    print('from father %s' %name)
    def son() :                            #这里的son 为局部变量,函数外部无法单独调用
        print('from father %s' %name)
    print(locals())
father('alex')

 

 #闭包——在每个作用域里封装变量

#装饰器框架

 

def timmer(func) :
    def wrapper():
        func()
    return wrapper()

 

#语法糖(一些python内置的语句,加在定义的函数前,用于修饰接下来定义的函数)

这里简单举例子:

 

def a(func):
    print(func())
    return func
@a                 # 做了以下处理 : b=a(b)
def b():
    return 'b函数'

 

#综合以上,我们就可以做一个简单装饰器(以计时器为例)

import time
def timmer(func):
    def wrapper():
        start_time=time.time()
        res=func()                   #用于获取返回值
        end_time=time.time()
        print('函数的运行时间为 %s s' %(end_time-start_time))
        return res                   #获取返回值
    return wrapper
@timmer
def function_test():
    time.sleep(1)
    print('函数运行完毕')
    return '这是返回值'
a = function_test()
print(a)                              #输出返回值

#被修饰的函数带有参数该如何处理?

 

import time
def timmer(func):
    def wrapper(*args,**kwargs):             #保证传入的是动态参数,不把参数定死
        start_time=time.time()
        res=func(*args,**kwargs)             #同上
        end_time=time.time()
        print('函数的运行时间为 %s s' %(end_time-start_time))
        return res
    return wrapper
@timmer
def sum1(x,y=1):
    time.sleep(1)
    for i in range(1,x+1):
        y=y*i
    return y
print('阶乘结果为:%s' %(sum1(3)))

 #小作业:查找、添加、替换、删除指定格式文本指定内容

#学习用局部变量tag控制逻辑判断的方法

 

tag = True
while tag:
    print('layer1')
    choice=input('输入:')
    if choice == 'quit':break
    if choice == 'quit_all': tag = False
    while tag:
        print('layer2')
        choice = input('输入:')
        if choice == 'quit': break
        if choice == 'quit_all':tag=False
        while tag:
            print('layer3')
            choice = input('输入:')
            if choice == 'quit': break             #不用tag控制的话,需要三次输入quit才能终止循环
            if choice == 'quit_all': tag = False   #用tag控制一次退出所有循环

 

#以下为作业

import os
def fetch(path,content):                      #打印第1和第2个含查找内容的行之前的文本
    with open(path,'r',encoding='utf8') as f :
        ret=[]
        tag=False                             #利用tag保存状态
        name = 'backend %s\n' %content
        for i in f :
            if i == name :
                tag=True
                continue                      #查到包含指定字符串的那行不要,跳入下一行
            if tag and i.startswith('backend'):
                tag = False
            if tag:
                print(i,end='')
                ret.append(i)
    return ret
def add(path,content):
    pass
def change(path,data):
    res = fetch(path,data[0])
    if not res or data[1] not in res:
        print('替换内容不存在')
    else:
        with open(path, 'r', encoding='utf8') as f, open('%s1' %path, 'w', encoding='utf8') as f1:
            tag=False
            count=False
            for i in f :
                if i == ('backend %s\n' %data[0]):
                    res.insert(0,'backend %s\n' %data[0])
                    tag=True
                    count=True
                    continue
                if tag and i.startswith('backend'):
                    tag = False
                if not tag:
                    f1.write(i)
                if tag:
                    if count:
                        for j in res:
                            if j == data[1]:
                                f1.write(data[2])
                            else:
                                f1.write(j)
                        count=False
    os.rename('test','test.bak')
    os.rename('test1','test')
    os.remove('test.bak')
    return '替换完毕'
def delete(path,content):
    pass
dic_func={
    '1':fetch,
    '2':add,
    '3':change,
    '4':delete
}
dic_func1={
    '1':'查找',
    '2':'添加',
    '3':'更改',
    '4':'替换'
}
msg='''1:查找\n2:添加\n3:更改\n4:删除\n5:退出
    '''
if __name__ == '__main__':                        #规范:把调用函数的代码写在这个判断语句下面,函数统一写在上方
    while True:
        print(msg)
        value = input('请选择功能:').strip()
        if not value :continue
        if value=='5':break
        data = input('请输入%s内容:' %dic_func1[value]).strip()
        path = input('请输入文件路径:').strip()
        if value == '3':
            data = eval(data)
        print(dic_func[value](path,data))
        break
    #3模式下输入的内容格式如下
    #['www.oldboy1.org','        server 2.2.2.7 2.2.2.7 weight 30 maxconn 4000\n','        此处已被修改\n']
View Code

 #程序的解耦(先这么理解:将函数重复的代码统一管理)

 1 import os
 2 def handle(path,res=None,x=None,y=None):                                 #把各个函数相同的部分统一写成一个函数
 3     if not y:
 4         with open(path,'r',encoding='utf8') as f :
 5             ret=[]
 6             tag=False                             #利用tag保存状态
 7             name = 'backend %s\n' %x
 8             for i in f :
 9                 if i == name :
10                     tag=True
11                     continue                      #查到包含指定字符串的那行不要,跳入下一行
12                 if tag and i.startswith('backend'):
13                     tag = False
14                 if tag:
15                     print(i,end='')
16                     ret.append(i)
17         return ret
18     else:
19         with open(path, 'r', encoding='utf8') as f, open('%s1' % path, 'w', encoding='utf8') as f1:
20             tag = False
21             count = False
22             for i in f:
23                 if i == ('backend %s\n' % data[0]):
24                     res.insert(0, 'backend %s\n' % data[0])
25                     tag = True
26                     count = True
27                     continue
28                 if tag and i.startswith('backend'):
29                     tag = False
30                 if not tag:
31                     f1.write(i)
32                 if tag:
33                     if count:
34                         for j in res:
35                             if j == data[1]:
36                                 f1.write(data[2])
37                             else:
38                                 f1.write(j)
39                         count = False
40     os.rename('test', 'test.bak')
41     os.rename('test1', 'test')
42     os.remove('test.bak')
43     return '替换完毕'
44 def fetch(path,content):                      #打印第1和第2个含查找内容的行之前的文本
45     return handle(path,x=content)
46 def add(path,content):
47     pass
48 def change(path,data):
49     res = fetch(path,data[0])
50     if not res or data[1] not in res:
51         print('替换内容不存在')
52     else:
53         return handle(path,res,x=None,y=data)
54 def delete(path,content):
55     pass
56 dic_func={
57     '1':fetch,
58     '2':add,
59     '3':change,
60     '4':delete
61 }
62 dic_func1={
63     '1':'查找',
64     '2':'添加',
65     '3':'更改',
66     '4':'替换'
67 }
68 msg='''1:查找\n2:添加\n3:更改\n4:删除\n5:退出
69     '''
70 if __name__ == '__main__':                        #规范:把调用函数的代码写在这个判断语句下面,函数统一写在上方
71     while True:
72         print(msg)
73         value = input('请选择功能:').strip()
74         if not value :continue
75         if value=='5':break
76         data = input('请输入%s内容:' %dic_func1[value]).strip()
77         path = input('请输入文件路径:').strip()
78         if value == '3':
79             data = eval(data)
80         print(dic_func[value](path,data))
81         break
82     #3模式下输入的内容格式如下
83     #['www.oldboy1.org','        server 2.2.2.7 2.2.2.7 weight 30 maxconn 4000\n','        此处已被修改\n']
View Code

 

posted @ 2019-01-22 19:37  Matrixssy  阅读(221)  评论(0)    收藏  举报