Frage

In dieser Kivy-Code:

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))

Offenbar Color und d und Ellipse befinden sich im Namensraum von self.canvas, aber woher weiß Python das userdata befindet sich nicht im selben Namensraum?

War es hilfreich?

Lösung

Bearbeiten:Diese Antwort wurde etwas langwierig, also hier ist die Zusammenfassung:

  1. with self.canvas definiert die aktuell aktive Leinwand für den folgenden Codeblock.
  2. Alle Zeichenanweisungen wie Color oder Ellipse zeichnen Sie auf der aktiven Leinwand.

Namespaces haben eigentlich nichts damit zu tun, es kommt auf den Kontext an (siehe unten).

Der with anweisung ermöglicht es Ihnen, sogenannte zu verwenden kontextmanager.

Die Syntax ist wie folgt

with thing [as foo]:

wo thing normalerweise ist eine Funktion mit dem verziert contextlib.contextmanager Dekorator.Was genau ein Kontextmanager tut, hängt davon ab, wie thing implementiert ist.

Aber was es nicht tut, ist, Variable magisch in Ihrem Bereich erscheinen zu lassen.Ein Verweis auf den Kontext kann durch das Optionale erhalten werden as foo klausel, aber das war's. Color und Ellipse in Ihrem Beispiel kommen von woanders (wahrscheinlich Importe?).

Um herauszufinden, was genau der Kontextmanager in der with self.canvas linie tut, sollten Sie sich das ansehen API-Dokumentation oder die Quellcode für kivy.graphics.instructions.Canvas.

Hier ist der relevante Auszug aus dem Tutorial:

Durch die Verwendung der with-Anweisung damit werden alle aufeinanderfolgenden Zeichenbefehle richtig eingerückte Elemente ändern diese Zeichenfläche.Die mit Aussage stellt auch sicher, dass nach unserer Zeichnung der interne Zustand gereinigt werden kann richtig hoch.

Also das verwenden von Color und Ellipse beeinflussen self.canvas, aber sie werden in keiner Weise durch die with Anweisung definiert.

Wenn Sie sich den Quellcode ansehen, funktioniert das so:

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

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

__enter__ und __exit__ definieren Sie, was passiert, wenn ein Kontextmanager eingegeben wird (vor der ersten Zeile des eingerückten Codes nach dem with anweisung) und beendet.

In diesem Fall wird die Leinwand einfach auf eine Stack dies definiert die aktuell aktive Zeichenfläche (und wird von dieser entfernt, wenn der Kontextmanager beendet wird).

In kivy.graphics.instructions.Instruction, die scheinbare Basisklasse für alle Zeichenanweisungen, die übergeordnetes Element wird auf die aktuell aktive Zeichenfläche gesetzt:

self.parent = getActiveCanvas()

Andere Tipps

Tatsächlich, Color und Ellipse werden importiert aus kivy.graphics etwas höher im Code:

from kivy.graphics import Color, Ellipse

Um Ihre Frage zu Namespaces zu beantworten, muss Python überhaupt nicht "wissen", aus welchem Namespace Variablen abgerufen werden.Es hat sehr einfache Namespace-Regeln im Vergleich zu Sprachen wie Java, die nacheinander nach Funktions-, Objekt-, Klassen-, globalen und Paketbereichen suchen.Python hat einen globalen Namespace (pro Modul) und einen Stapel lokaler Namespaces (z.verschachtelte Funktionen können auf die Variablen von äußeren Funktionen zugreifen).Es geht einfach die Liste der Bereiche durch, bis es den fraglichen Variablennamen findet.

Der with die obige Aussage hat eine besondere Bedeutung, aber ich denke sogar with kann keine neuen Variablen implizit in den lokalen Bereich einführen (es kann eine Variable explizit mit der as klausel).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top