Pythonで動的にローカライズされたスコープを作成することは可能ですか?

ノバーク

実行時に関数を動的に実行していて、「ローカライズされた」スコープを追跡する必要があるシナリオがあります。以下の例では、「startScope」と「endScope」は実際には「ネスト」のレベルを作成します(実際には、このローカライズされたスコープに含まれるものは出力ステートメントではありません...他の場所にデータを送信する関数呼び出しとネストですstartScope / endScopeは、現在のネストの深さを開始/終了するために使用される制御フラグを設定するだけです)。

これはすべて、ネストされたデータの追跡には問題なく機能しますが、例外は別の問題です。理想的には、例外により、現在のローカライズされたスコープから「脱落」し、関数全体(以下の例ではmyFunction)が終了しません。

def startScope():
    #Increment our control object's (not included in this example) nesting depth
    control.incrementNestingDepth()

def endScope():
    #Decrement our control object's (not included in this example) nesting depth
    control.decrementNestingDepth()

def myFunction():
    print "A"
    print "B"

    startScope()
    print "C"
    raise Exception
    print "D"
    print "This print statement and the previous one won't get printed"
    endScope()

    print "E"

def main():
    try:
        myFunction()
    except:
        print "Error!"

これを実行すると、(理論的には)次のように出力されます。

>>> main()
A
B
C
Error!
E

>>>

上で書いたように、これは不可能だと確信しています。私は、達成しようとしている最終結果のような絵を描きたかっただけです。

このようなことはPythonで可能ですか?

編集:これが実際にどのように使用されているかについてのより関連性のある(長いですが)例:

class Log(object):
    """
    Log class
    """

    def __init__(self):
        #DataModel is defined elsewhere and contains a bunch of data structures / handles nested data / etc...
        self.model = DataModel()

    def Warning(self, text):
        self.model.put("warning", text)

    def ToDo(self, text):
        self.model.put("todo", text)

    def Info(self, text):
        self.model.put("info", text)

    def StartAdvanced(self):
        self.model.put("startadvanced")

    def EndAdvanced(self):
        self.model.put("endadvanced")

    def AddDataPoint(self, data):
        self.model.put("data", data)

    def StartTest(self):
        self.model.put("starttest")

    def EndTest(self):
        self.model.put("endtest")

    def Error(self, text):
        self.model.put("error", text)


#myScript.py

from Logger import Log

def test_alpha():
    """
    Crazy contrived example

    In this example, there are 2 levels of nesting...everything up to StartAdvanced(),
    and after EndAdvanced() is included in the top level...everything between the two is
    contained in a separate level.
    """

    Log.Warning("Better be careful here!")
    Log.AddDataPoint(fancyMath()[0])

    data = getSerialData()

    if data:
        Log.Info("Got data, let's continue with an advanced test...")

        Log.StartAdvanced()

        #NOTE: If something breaks in one of the following methods, then GOTO (***)
        operateOnData(data)
        doSomethingCrazy(data)
        Log.ToDo("Fill in some more stuff here later...")
        Log.AddDataPoint(data)

        Log.EndAdvanced()

    #(***) Ideally, we would resume here if an exception is raised in the above localized scope
    Log.Info("All done!  Log some data and wrap everything up!")
    Log.AddDataPoint({"data": "blah"})

    #Done


#framework.py

import inspect
from Logger import Log

class Framework(object):

    def __init__(self):
        print "Framework init!"
        self.tests = []

    def loadTests(self, file):
        """
        Simplifying this for the sake of clarity
        """

        for test in file:
            self.tests.append(test)

    def runTests(self):
        """
        Simplifying this for the sake of clarity
        """

        #test_alpha() as well as any other user tests will be run here
        for test in self.tests:
            Log.StartTest()

            try:
                test()
            except Exception,e :
                Log.Error(str(e))

            Log.EndTest()

#End
ブレンバーン

withステートメントを使用して、コンテキストマネージャーで同様の効果を実現できます。ここではcontextlib.contextmanagerデコレータを使用します

@contextlib.contextmanager
def swallower():
    try:
        yield
    except ZeroDivisionError:
        print("We stopped zero division error")

def foo():
    print("This error will be trapped")
    with swallower():
        print("Here comes error")
        1/0
        print("This will never be reached")
    print("Merrily on our way")
    with swallower():
        print("This error will propagate")
        nonexistentName
    print("This won't be reached")

>>> foo()
This error will be trapped
Here comes error
We stopped zero division error
Merrily on our way
This error will propagate
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    foo()
  File "<pyshell#3>", line 10, in foo
    nonexistentName
NameError: global name 'nonexistentName' is not defined

あなたの例のように、通常の関数呼び出しでは実行できません。あなたの例では、関数startScopemyFunction実行の残りの部分の前に戻るので、それにstartScope影響を与えることはできません。例外を処理するには、;内にある種の明示的な構造(withステートメントまたは通常のtry/except)が必要myFunctionです。単純な関数呼び出しで、呼び出し元で発生した例外を魔法のようにインターセプトする方法はありません。

コンテキストマネージャーは、あなたがやろうとしていることに合っているように見えるので、よく読んでください。コンテキストマネージャの方法は、あなたに対応するであろうそれがあなたが望むことを正確に行うかどうかは、それらの「マネージャー」関数に何をさせたいかによって異なりますが、単純な関数呼び出しでそれをしようとするよりも、コンテキストマネージャーでそれを行うほうが幸運です。__enter____exit__startScopeendScope

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

フォークされたLinuxプロセスのコピーオンライトを監視することは可能ですか?(具体的にはPython)

分類Dev

XAMLの基本クラス(この場合はStackPanel)のようにカスタマイズされたWPFコントロールを使用することは(不可能です)可能ですか?

分類Dev

Python IDEに動的に生成されたクラス属性のオートコンプリートを提供させることは可能ですか?

分類Dev

Python:プロットされた時系列コロプレスでカラーバーを静的にすることはできますか?

分類Dev

アラートがiOSで最初に表示されたときにBluetoothメッセージをカスタマイズすることは可能ですか?

分類Dev

Rails4でconfig / application.rbのカスタマイズされたテンプレートを作成することは可能ですか?

分類Dev

コードからではなく開始されたプロセスのjava.lang.Processインスタンスを作成することは可能ですか?

分類Dev

ローカライズされたテキストでvue固有のディレクティブを使用することは可能ですか?

分類Dev

より多くにパイプされた出力をカラー化することは可能ですか?

分類Dev

ユニバーサルアプリでローカライズされたリソースを備えたポータブルライブラリを使用することは可能ですか?

分類Dev

ストーリーボードのUITabBarItemテキストを自動的にローカライズすることは可能ですか?

分類Dev

アップロードされたファイルの<ahref ... </ a>をphpで作成することは可能ですか?

分類Dev

JetBrains MPSによって作成されたDSLコンパイラをエクスポートして、独立して使用することは可能ですか(たとえば、別のJavaプログラムから呼び出す)。

分類Dev

標準ライブラリを使用してGoにネストされたテンプレートを作成することは可能ですか?

分類Dev

アラームクロックがオフになったときに起動されるJobServiceを作成することは可能ですか?

分類Dev

あるC#プロジェクトから別のプロジェクトにクラスをインポートするときに自動生成されたファイルを除外することは可能ですか?

分類Dev

明示的に実装されたインターフェイスプロパティを使用してクラスをjson-serializeすることは可能ですか?

分類Dev

Swiftでローカライズされた説明とエラータイプを提供するにはどうすればよいですか?

分類Dev

tornadofxでカスタマイズされたUIコンポーネントを作成するためのベストプラクティスは何ですか?

分類Dev

Salesforceでカスタマイズされたログインコンポーネントを作成するにはどうすればよいですか?

分類Dev

アレグログラフで新しい関係を推測するためにカスタマイズされたルールを追加することは可能ですか?

分類Dev

CoreBluetoothによって記録されたエラーコードにプログラムでアクセスすることは可能ですか?

分類Dev

それは、ファイルの移動、コピーになりますかどうかをプログラム的に決定することは可能ですか?

分類Dev

Pythonでリストのサイズを修正して、リストにそれ以上のサイズが含まれている場合にエラーがスローされるようにすることは可能ですか?

分類Dev

Pytorch:パラメータやサイズが変更されたときにモデルをロードすることは可能ですか?

分類Dev

カスタムEditorTemplatesをMVCビューからc#クラスライブラリプロジェクトに移動することは可能です

分類Dev

デプロイされた.NETMVCRazorサイトにビューを追加することは可能ですか?

分類Dev

ブラウザのフォームを作成し、ブラウザがオンラインになったときにデータをローカルに保存し、送信されたデータを保存することは可能ですか?

分類Dev

定義されたホストのコピーモジュールを使用するプレイ内にプレイを追加することは可能ですか?

Related 関連記事

  1. 1

    フォークされたLinuxプロセスのコピーオンライトを監視することは可能ですか?(具体的にはPython)

  2. 2

    XAMLの基本クラス(この場合はStackPanel)のようにカスタマイズされたWPFコントロールを使用することは(不可能です)可能ですか?

  3. 3

    Python IDEに動的に生成されたクラス属性のオートコンプリートを提供させることは可能ですか?

  4. 4

    Python:プロットされた時系列コロプレスでカラーバーを静的にすることはできますか?

  5. 5

    アラートがiOSで最初に表示されたときにBluetoothメッセージをカスタマイズすることは可能ですか?

  6. 6

    Rails4でconfig / application.rbのカスタマイズされたテンプレートを作成することは可能ですか?

  7. 7

    コードからではなく開始されたプロセスのjava.lang.Processインスタンスを作成することは可能ですか?

  8. 8

    ローカライズされたテキストでvue固有のディレクティブを使用することは可能ですか?

  9. 9

    より多くにパイプされた出力をカラー化することは可能ですか?

  10. 10

    ユニバーサルアプリでローカライズされたリソースを備えたポータブルライブラリを使用することは可能ですか?

  11. 11

    ストーリーボードのUITabBarItemテキストを自動的にローカライズすることは可能ですか?

  12. 12

    アップロードされたファイルの<ahref ... </ a>をphpで作成することは可能ですか?

  13. 13

    JetBrains MPSによって作成されたDSLコンパイラをエクスポートして、独立して使用することは可能ですか(たとえば、別のJavaプログラムから呼び出す)。

  14. 14

    標準ライブラリを使用してGoにネストされたテンプレートを作成することは可能ですか?

  15. 15

    アラームクロックがオフになったときに起動されるJobServiceを作成することは可能ですか?

  16. 16

    あるC#プロジェクトから別のプロジェクトにクラスをインポートするときに自動生成されたファイルを除外することは可能ですか?

  17. 17

    明示的に実装されたインターフェイスプロパティを使用してクラスをjson-serializeすることは可能ですか?

  18. 18

    Swiftでローカライズされた説明とエラータイプを提供するにはどうすればよいですか?

  19. 19

    tornadofxでカスタマイズされたUIコンポーネントを作成するためのベストプラクティスは何ですか?

  20. 20

    Salesforceでカスタマイズされたログインコンポーネントを作成するにはどうすればよいですか?

  21. 21

    アレグログラフで新しい関係を推測するためにカスタマイズされたルールを追加することは可能ですか?

  22. 22

    CoreBluetoothによって記録されたエラーコードにプログラムでアクセスすることは可能ですか?

  23. 23

    それは、ファイルの移動、コピーになりますかどうかをプログラム的に決定することは可能ですか?

  24. 24

    Pythonでリストのサイズを修正して、リストにそれ以上のサイズが含まれている場合にエラーがスローされるようにすることは可能ですか?

  25. 25

    Pytorch:パラメータやサイズが変更されたときにモデルをロードすることは可能ですか?

  26. 26

    カスタムEditorTemplatesをMVCビューからc#クラスライブラリプロジェクトに移動することは可能です

  27. 27

    デプロイされた.NETMVCRazorサイトにビューを追加することは可能ですか?

  28. 28

    ブラウザのフォームを作成し、ブラウザがオンラインになったときにデータをローカルに保存し、送信されたデータを保存することは可能ですか?

  29. 29

    定義されたホストのコピーモジュールを使用するプレイ内にプレイを追加することは可能ですか?

ホットタグ

アーカイブ