装饰器思考题

        装饰器的最大用处,就是关联操作,或者叫同步,或者叫联动。当你有几种操作需要同步时,考虑到使用装饰器,就会产生多个装饰器“位置摆放疑团”。

import sqlite3

def opendb2(f):
    def operatedb(dbPath=r"C:\Users\Administrator\Desktop\107.db",*tableName):
        print("trying to connect DB...")
        connt = sqlite3.connect(dbPath)
        print("TASK FINISHED!")
        return f(connt,*tableName)
    return operatedb

@opendb2
def anyfunction():
    ...

        比如以上的数据库打开操作,当你看到其中实际执行前后都有输出提示信息,可以继续习惯性抽出装饰器里的东西,变成日志型装饰器。

import sqlite3

def tipslog(f):
    def innerdo(*x):
        print("trying to connect DB...")
        a = f(*x)
        print("TASK FINISHED!")
        return a
    return innerdo

def opendb2(f):
    #单独看效果,或者放在本装饰器的外层,或者放在其他需要装饰之函数的外层
    #然而深究起每一种位置的传入函数来,却不一样
    @tipslog
    def operatedb(dbPath,*tableName):
        connt = sqlite3.connect(dbPath)
        return f(connt,*tableName)
    return operatedb

@opendb2
def any_function(any_parameter):
    ...
    

        现在有两个装饰器定义了,问题也来了:(1)两个装饰器分别要摆什么位置?(2)每一种位置有什么区别?

import sqlite3

def tipslog(f):
    def innerdo(*x):
        print("trying to connect DB...")
        a = f(*x)
        print("TASK FINISHED!")
        return a
    return innerdo

#第二种位置,连续调用any_function时只有第一个生效。
#实际上是后面@本装饰器时已经执行了
@tipslog
def opendb2(f):
    def operatedb(dbPath,*tableName):
        connt = sqlite3.connect(dbPath)
        return f(connt,*tableName)
    return operatedb

@opendb2
def any_function(any_parameter):
    ...
    

import sqlite3

def tipslog(f):
    def innerdo(*x):
        print("trying to connect DB...")
        a = f(*x)
        print("TASK FINISHED!")
        return a
    return innerdo

def opendb2(f):
    def operatedb(dbPath,*tableName):
        connt = sqlite3.connect(dbPath)
        return f(connt,*tableName)
    return operatedb

@tipslog#第三种位置
@opendb2
def any_function(any_parameter):
    ...

        当然在实际中应用,其实可以顺着自己抽象的思路,放在就近关联的位置,比如第一种摆法,像膏药一样贴着原先属于的函数,最终形成套娃。

        附加题:

from time import time
import sqlite3

def time_cost(f):
    def core(*x):
        begin = time()
        r = f(*x)
        end = time()
        print("耗时","{:.4f}s".format(end - begin))
        return r
    return core

def tipslog(f):
    #@time_cost
    def innerdo(*x):
        print("尝试连接数据库...")
        try:
            a = f(*x)
            print("TASK FINISHED!")
        except:
            a = None
            print("数据库矬啦!请检查参数({})".format(x))
        return a
    return innerdo
 
def opendb2(f):
    #@time_cost
    @tipslog
    #@time_cost
    def operatedb(dbPath,*tableName):
        connt = sqlite3.connect(dbPath)
        return f(connt,*tableName)
    return operatedb

@time_cost
@opendb2
#@time_cost
def any_function(any_parameter):
    print(any_parameter)


any_function()
any_function(578)

可以看到,当装饰器增多时,可能的摆放组合是阶乘式增长的(运行结果也极其烧脑),而且一旦有异常处理,调试定位也极其麻烦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值