使用 - 如何知道上下文中的变量

时间:2012-10-02 15:13:28

标签: python kivy

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

显然Colord以及Ellipse位于self.canvas的命名空间内,但Python如何知道userdata不在同一个命名空间内?

2 个答案:

答案 0 :(得分:5)

编辑:这个答案有点冗长,所以这里是摘要:

  1. with self.canvas为以下代码块定义当前活动画布
  2. 所有绘图说明,例如ColorEllipse在活动画布上绘制。
  3. 命名空间与它没有任何关系,重要的是上下文(见下文)。

    with语句允许您使用所谓的context managers

    语法就像这样

    with thing [as foo]:
    

    其中thing通常是用contextlib.contextmanager装饰器修饰的函数。上下文管理器究竟做了什么取决于thing的实现方式。

    但它没有做的是让变量神奇地出现在你的范围内。可以通过可选的as foo子句获得对上下文的引用,但就是这样。您示例中的ColorEllipse来自其他地方(可能是导入?)。

    为了找出with self.canvas行中的上下文管理器究竟是什么,您应该查看kivy.graphics.instructions.Canvas的{​​{3}}或API documentation

    以下是教程的相关摘录:

      

    通过对它使用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中,所有绘图说明的明显基类,source code

    self.parent = getActiveCanvas()
    

答案 1 :(得分:1)

实际上,ColorEllipsekivy.graphics导入了更高的代码:

from kivy.graphics import Color, Ellipse

要回答关于命名空间的问题,python并不需要知道"知道"它从什么名称空间获取变量。与Java等语言相比,它具有非常简单的命名空间规则,Java一个接一个地搜索函数,对象,类,全局和包范围。 Python有一个全局命名空间(每个模块)和一堆本地命名空间(例如嵌套函数可以从外部函数获取变量)。它只是在范围列表中查找,直到找到有问题的变量名称。

上面的with语句具有特殊含义,但我认为即使with也无法将新变量隐式地引入本地范围(它可以使用{{1}显式引入一个变量但是,条款。