被调用者是否有可能强制其调用者在python中返回?

时间:2013-01-25 13:28:36

标签: python introspection

被调用者是否有可能强制其调用者在python中返回? 如果是这样,这是一个好方法吗?它不违反明确比Zen of Python的隐含。句更好吗?

示例:

import inspect

class C(object):
    def callee(self):
        print 'in callee'
        caller_name = inspect.stack()[1][3]
        caller = getattr(self, caller_name)
        # force caller to return
        # so that "in caller after callee" gets never printed

        caller.return() # ???

    def caller(self):
        print 'in caller before calle'
        self.callee()
        print 'in caller after callee'

c = C()

c.caller()

print 'resume'

输出:

in caller before callee
in callee
resume

最后,感谢@Andrew Jaffe对上下文管理器的建议,我用一个简单的装饰器解决了这个问题。

# In my real code this is not a global variable
REPORT_ERRORS = True

def error_decorator(func):
    """
    Returns Event instance with result of the
    decorated function, or caught exception.
    Or reraises that exception.
    """

    def wrap():
        error = None
        user = None

        try:
            user = func()
        except Exception as e:
            error = e
        finally:
            if REPORT_ERRORS:
                return Event(user, error)
            else:
                raise error 
    return wrap


@error_decorator
def login():

    response = fetch_some_service()

    if response.errors:
        # flow ends here
        raise BadResponseError

    user = parse_response(response)

    return user

2 个答案:

答案 0 :(得分:5)

从被叫方返回一个值,由调用者读取并因此表现相应有什么问题?

而不是

caller.return() # ???

return False

并在

def caller(self):
        print 'in caller before calle'

        rc = self.callee()
        if not rc:
             return
        print 'in caller after callee'

当然你可以提出异常并在被叫方中捕获它并相应地表现或者通过来减少

mgilson复制

我会主张基于退货值的检查

  1. Explicit is better than implicit
  2. Callee不应该控制来电者行为。这是一个糟糕的编程习惯。相反,调用者应该根据被调用者的行为改变其行为。

答案 1 :(得分:3)

从某种意义上说,您可以使用例外情况执行此操作...只需在callee结尾处引发异常,并且不要在caller中处理它...为什么要做到这一点?这个?看起来似乎有更好的方法来做你正在尝试的任何事情......


就在被叫方中创建跳转而言,看起来这是不可能的。从Frame对象的Data Model部分(重点是我的)

  

f_lineno是帧的当前行号 - 从跟踪函数内写入此跳转到给定行(仅适用于最底部的帧)。调试器可以通过写入f_lineno来实现Jump命令(也称为Set Next Statement)。