1

被调用者是否可以强制其调用者在 python 中返回?如果是这样,这是一个好方法吗?它不违反显式优于隐式。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
4

2 回答 2

5

What's wrong in returning a value from the callee, to be read by caller and thus behave accordingly?

instead of

caller.return() # ???

write

return False

and in

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

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

and off course you can raise exception and catch it in the callee and behave accordingly or simply less it fall through

Duplicate of mgilson

Reason I would argue for Return Value based check

  1. Explicit is better than implicit
  2. 被调用者不应控制调用者行为。这是一种糟糕的编程习惯。相反,调用者应该根据被调用者的行为改变其行为。
于 2013-01-25T13:32:20.177 回答
3

从某种意义上说,你可以用异常来做到这一点......只是在最后引发一个异常,callee而不是在caller......你为什么要这样做?似乎有更好的方法来做你正在尝试的任何事情......


As far as creating a jump in the callee, it looks like that is impossible. From the Data Model section on Frame objects (emphasis is mine)

f_lineno is the current line number of the frame — writing to this from within a trace function jumps to the given line (only for the bottom-most frame). A debugger can implement a Jump command (aka Set Next Statement) by writing to f_lineno.

于 2013-01-25T13:31:01.727 回答