1

呼び出し先が呼び出し元を強制的に 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
4

2 に答える 2

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. 呼び出し先は、呼び出し元の動作を制御するべきではありません。その悪いプログラミングの練習。代わりに、呼び出し元は、呼び出し先の動作に基づいて動作を変更する必要があります。
于 2013-01-25T13:32:20.177 に答える
3

ある意味では、例外を使用してこれを行うことができます...終了時に例外を発生させ、calleeそれを処理しないでcallerください...なぜこれをしたいのですか? あなたが試みていることは何でもするためのより良い方法がおそらくあるようです...


呼び出し先でジャンプを作成する限り、それは不可能のようです。フレームオブジェクトのデータモデルセクションから(強調は私のものです)

f_lineno はフレームの現在の行番号です — トレース関数内からこれに書き込むと、指定された行にジャンプします(一番下のフレームのみ)。デバッガーは、f_lineno に書き込むことにより、Jump コマンド (別名 Set Next Statement) を実装できます。

于 2013-01-25T13:31:01.727 に答える