Pregunta

En este código 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))

Aparentemente Color y d y Ellipse están dentro del espacio de nombres de self.canvas, pero ¿cómo sabe Python eso? userdata ¿No está dentro de ese mismo espacio de nombres?

¿Fue útil?

Solución

Editar:Esta respuesta se volvió un poco larga, así que aquí está el resumen:

  1. with self.canvas define la actualidad lienzo activo para el siguiente bloque de código.
  2. Todas las instrucciones de dibujo como Color o Ellipse dibujar en el lienzo activo.

Los espacios de nombres realmente no tienen nada que ver con eso, lo que importa es el contexto (ver más abajo).

El with La declaración le permite utilizar los llamados administradores de contexto.

La sintaxis es así.

with thing [as foo]:

dónde thing suele ser una función decorada con el contextlib.contextmanager decorador.Lo que hace exactamente un administrador de contexto depende de cómo thing está implementado.

Pero lo que no hace es hacer que la variable aparezca mágicamente en su alcance.Se puede obtener una referencia al contexto mediante la opción opcional as foo cláusula, pero eso es todo. Color y Ellipse en su ejemplo provienen de otro lugar (¿probablemente importaciones?).

Para saber qué es exactamente el administrador de contexto en el with self.canvas línea lo hace, deberías mirar el Documentación API o el código fuente para kivy.graphics.instructions.Canvas.

Aquí está el extracto relevante del tutorial:

Al usar la declaración con él, todos los comandos de dibujo sucesivos que están correctamente sangrados modificarán este lienzo.La declaración con la declaración también se asegura de que después de nuestro dibujo, el estado interno se pueda limpiar correctamente.

Entonces el usar de Color y Ellipse afecta self.canvas, pero no están definidos de ninguna manera por la declaración with.

Mirando el código fuente, así es como funciona:

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

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

__enter__ y __exit__ definir qué sucede si se ingresa un administrador de contexto (antes de la primera línea de código sangrado después del with declaración) y salió.

En este caso, el lienzo simplemente se empuja sobre un pila que define el lienzo actualmente activo (y sale de él si se sale del administrador de contexto).

En kivy.graphics.instructions.Instruction, la clase base aparente para todas las instrucciones de dibujo, la padre está configurado en el lienzo actualmente activo:

self.parent = getActiveCanvas()

Otros consejos

De hecho, Color y Ellipse son importados de kivy.graphics un poco más arriba en el código:

from kivy.graphics import Color, Ellipse

Para responder a su pregunta sobre los espacios de nombres, Python no necesita "saber" de qué espacio de nombres obtiene variables.Tiene reglas de espacio de nombres muy simples en comparación con lenguajes como Java, que buscan alcances de función, objeto, clase, global y paquete uno tras otro.Python tiene un espacio de nombres global (por módulo) y una pila de espacios de nombres locales (p. ej.las funciones anidadas pueden acceder a las variables desde funciones externas).Simplemente recorre la lista de ámbitos hasta que encuentra el nombre de la variable en cuestión.

El with La afirmación anterior tiene un significado especial, pero creo que incluso with no puede introducir implícitamente nuevas variables en el ámbito local (puede introducir una variable explícitamente con el as cláusula, sin embargo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top