0

このKivyコードでは:

class MyPaintWidget(Widget):
    def on_touch_down(self, touch):
        userdata = touch.ud
        with self.canvas:
            Color(1, 1, 0)
            d = 30.
            Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
            userdata['line'] = Line(points=(touch.x, touch.y))

どうやらColoranddEllipseは の名前空間内にあるようですが、Python はそれが同じ名前空間内にないself.canvasことをどのように知るのでしょうか?userdata

4

2 に答える 2

5

編集:この回答は少し長くなったので、要約を次に示します。

  1. with self.canvas次のコード ブロックの現在アクティブなキャンバスを定義します。
  2. すべての描画命令は、アクティブなキャンバスに似ているColorか描画します。Ellipse

名前空間は実際には何の関係もありません。重要なのはコンテキストです (以下を参照)。

このwithステートメントを使用すると、いわゆるコンテキスト マネージャーを使用できます。

構文はこのようなものです

with thing [as foo]:

ここで、thing通常はcontextlib.contextmanagerデコレータで装飾された関数です。コンテキストマネージャが正確に何をするかthingは、実装方法によって異なります。

しかし、それがしないのは、変数を魔法のようにスコープに表示することです。コンテキストへの参照は、オプションのas foo句によって取得される場合がありますが、それだけです。Colorあなたの例でEllipseは、どこかから来ています(おそらく輸入品ですか?)。

with self.canvas行内のコンテキスト マネージャが正確に何を行うかを確認するには、 API ドキュメントまたは のソース コードを参照する必要がありますkivy.graphics.instructions.Canvas

チュートリアルからの関連する抜粋は次のとおりです。

with ステートメントを一緒に使用することにより、適切にインデントされたすべての連続する描画コマンドがこのキャンバスを変更します。with ステートメントは、描画後に内部状態を適切にクリーンアップできることも保証します。

したがって、 と の使用ColorEllipse影響self.canvasしますが、with ステートメントではまったく定義されていません。

ソース コードを見ると、次のように動作します。

def class CanvasBase(InstructionGroup):
    def __enter__(self):
        pushActiveCanvas(self)

    def __exit__(self, *largs):
        popActiveCanvas()

__enter____exit__また、コンテキスト マネージャーが (withステートメントの後のインデントされたコードの最初の行の前に)入力され、終了した場合に何が起こるかを定義します。

この場合、キャンバスは、現在アクティブなキャンバスを定義するスタックに単純にプッシュされます (コンテキスト マネージャーが終了している場合はそこからポップされます)。

ではkivy.graphics.instructions.Instruction、すべての描画命令の見かけ上の基本クラスであり、親は現在アクティブな canvas に設定されます

self.parent = getActiveCanvas()
于 2012-10-02T15:25:16.207 に答える
1

実際にColorは、コードの少し上位Ellipseからインポートされます。kivy.graphics

from kivy.graphics import Color, Ellipse

名前空間に関するあなたの質問に答えるために、Python は変数を取得している名前空間を「知る」必要はまったくありません。関数、オブジェクト、クラス、グローバル、およびパッケージのスコープを次々に検索する Java などの言語と比較して、名前空間のルールは非常に単純です。Python には 1 つのグローバル名前空間 (モジュールごと) とローカル名前空間のスタックがあります (たとえば、ネストされた関数は外部関数から変数を取得できます)。問題の変数名が見つかるまで、スコープのリストをたどっていきます。

上記のステートメントには特別な意味がありますが、ローカルスコープに新しい変数を暗黙的に導入することwithさえできないと思います(ただし、句で1つの変数を明示的に導入することはできます)。withas

于 2012-10-02T15:24:06.957 に答える