utilizzando con - come conoscere le variabili che sono all'interno del contesto

StackOverflow https://stackoverflow.com//questions/12693136

  •  12-12-2019
  •  | 
  •  

Domanda

In questo Kivy codice:

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

A quanto pare Color e d e Ellipse sono all'interno del namespace di self.canvas, ma come si fa a sapere che Python userdata non è all'interno dello stesso spazio dei nomi?

È stato utile?

Soluzione

Modifica:Questa risposta ha un po ' lunga, quindi, ecco il riepilogo:

  1. with self.canvas definisce attualmente attivo tela per il seguente blocco di codice.
  2. Tutte le istruzioni di disegno, come Color o Ellipse disegnare su active tela.

Gli spazi dei nomi non hanno davvero nulla a che fare con esso, è il contesto che conta (vedi sotto).

Il with istruzione consente di utilizzare i cosiddetti contesto gestori.

La sintassi è simile a questo

with thing [as foo]:

dove thing di solito è una funzione decorato con la contextlib.contextmanager decoratore.Che cosa è esattamente un contesto manager non dipende da come thing è implementato.

Ma che cosa non fare è rendere variabile magicamente appaiono nel vostro ambito.Un riferimento al contesto può essere ottenuta con l'opzionale as foo la clausola, ma questo è tutto. Color e Ellipse nel tuo esempio sono venuta da qualche altra parte (probabilmente di importazione?).

Per scoprire che cosa esattamente il contesto manager in with self.canvas linea non si deve guardare il La documentazione delle API o il il codice sorgente per kivy.graphics.instructions.Canvas.

Ecco il relativo estratto dal tutorial:

Con l'istruzione, con essa, tutti i successivi comandi di disegno ben rientrato a modificare questa tela.L'istruzione con inoltre fa in modo che dopo il nostro disegno, stato interno può essere pulito in modo corretto.

Così il utilizzare di Color e Ellipse colpisce self.canvas, ma non sono definiti in alcun modo l'istruzione with.

Guardando il codice sorgente, questo è come funziona:

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

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

__enter__ e __exit__ definire che cosa succede se un contesto manager è inserito (prima della prima riga di codice indentato dopo il with istruzione) e chiuso.

In questo caso, la tela viene semplicemente spinto su un stack che definisce attivo tela (e spuntato da esso se il contesto manager è uscito).

In kivy.graphics.instructions.Instruction, l'apparente classe base per tutte le istruzioni per il disegno, la genitore è impostato su attivo tela:

self.parent = getActiveCanvas()

Altri suggerimenti

In realtà, Color e Ellipse vengono importati da kivy.graphics un po 'più alto nel codice:

from kivy.graphics import Color, Ellipse
.

Per rispondere alla tua domanda sugli spazi dei nomi, Python non ha bisogno di "sapere" quale spazio dei nomi sta ricevendo le variabili.Ha semplici semplici regole dello spazio dei nomi rispetto alle lingue come Java, che la funzione di ricerca, oggetto, classe, globale e pacchetto antichi uno dopo l'altro.Python ha uno spazio dei nomi globali (per modulo) e una pila di spazi dei nomi locali (E.G. Le funzioni nidificate possono ottenere nelle variabili dalle funzioni esterne).Scende solo la lista degli ambiti finché non trova il nome della variabile in questione.

L'istruzione with di cui sopra ha un significato speciale, ma penso che anche with non riesca implicitamente introdurre nuove variabili nell'ambito locale (può introdurre una variabile esplicitamente con la clausola as, però).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top