【问题标题】:Would decorated function calling another decorator function return normally?调用另一个装饰器函数的装饰函数会正常返回吗?
【发布时间】:2014-03-18 14:50:59
【问题描述】:

在装饰器的情况下控制流如何工作?无论如何我可以修改 calleedec 并使其在被调用后不返回给调用者吗?这不是我想要的场景,我看到了一个类似的错误,所以想知道这是否可能? 不就是和普通函数一样吗?

尝试调试问题 - 我们点击了第一个 pdb,但没有点击第二个 pdb,如下图所示?

两者都是装饰函数。

@cooldec()
def caller():
    import pdb;pbd.set_trace()  # Hits here
    callee()
    import pdb;pdb.set_trace() # Not here

@calleedec()
def callee():
    return "Okay

编辑:

引发错误是一种情况,但没有错误跟踪。

我可以看到被调用者的装饰器处于无限循环或无法完成其工作(需要很长时间)的情况,这可能会发生。

【问题讨论】:

  • 您希望calee 返回并以某种方式跳出其父函数吗?
  • 想知道这是否可能 - 我不想,但我看到了这样的错误。我假设 calle 完成后它必须返回。
  • 我认为,如果您在返回后直接根据callee 的返回值放置一个条件,该条件也可以从其调用者返回,但以某种方式重构可能会更简单,以便这是没有必要的。例如,如果有人不得不调试您的装饰器,那么内部逻辑就会非常混乱。
  • 我想callee 可能会引发异常。
  • 它可能的被调用者也是一个无限循环吧?

标签: python decorator


【解决方案1】:

装饰函数只是普通函数,在程序流程方面没有什么特别之处。

如有疑问,请尝试扩展装饰器,看看是否更清晰:

def calleedec(callee_fn):
    def wrapped():
        print("Running the callee")
        callee_fn()
    return wrapped

def callee():
    return "Okay"

callee = calleedec(callee)

def cooldec(fn):
    def wrapped():
        print("Running the caller")
        return fn()
    return wrapped

@cooldec
def caller():
    print("caller: start")
    callee()
    print("caller: end")

caller()

# Running the caller
# caller: start
# Running the callee
# caller: end

为了避免被调用者劫持流程而不返回调用者函数,您需要对堆栈执行一些严肃的黑魔法。所以我认为你不必担心这个。

如果您没有遇到第二个 pdb 断点,则可能是您的被调用函数中发生了某些事情。

【讨论】:

    猜你喜欢
    • 2020-04-28
    • 2019-11-05
    • 2016-10-20
    • 1970-01-01
    • 2021-09-10
    • 2020-05-20
    • 2021-04-06
    • 1970-01-01
    • 2021-06-24
    相关资源
    最近更新 更多