Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Kivy中,`with canvas:`(Python`with something()作为x:`)是如何隐式工作的?_Python_Kivy - Fatal编程技术网

在Kivy中,`with canvas:`(Python`with something()作为x:`)是如何隐式工作的?

在Kivy中,`with canvas:`(Python`with something()作为x:`)是如何隐式工作的?,python,kivy,Python,Kivy,我刚刚意识到,至少对我来说,在Kivy中使用with Python语句添加顶点指令的方式有些神秘。例如,使用with的方式如下所示: ... some code class MyWidget(Widget) ... some code def some_method (self): with self.canvas: Rectangle(pos=self.pos, size=self.size) 起初,我认为这只是我偶尔使用的with

我刚刚意识到,至少对我来说,在Kivy中使用with Python语句添加顶点指令的方式有些神秘。例如,使用with的方式如下所示:

... some code
class MyWidget(Widget)
    ... some code 

    def some_method (self):
        with self.canvas:
           Rectangle(pos=self.pos, size=self.size)
起初,我认为这只是我偶尔使用的with Python语句。但我突然意识到不是这样。通常,它看起来更像以下示例:

实例后面通常有as,对象后面有类似和别名的内容。在Kivy示例中,我们没有定义和别名,这仍然可以。但让我困惑的是,指令矩形仍然与self.canvas关联。在阅读了with语句之后,我非常确信Kivy代码应该这样编写:

class MyWidget(Widget)
    ... some code 

    def some_method (self):
        with self.canvas as c:
           c.add (Rectangle(pos=self.pos, size=self.size))
我假设在内部add方法就是被调用的方法。假设我们可以简单地添加带有self.add Rectanglepos=self.pos、size=self.size的矩形

我是否遗漏了with Python语句的某些内容?或者这是Kivy实现的吗?

with语句没有什么特别神奇的地方,但您可能不知道它是如何工作的

为了在with语句中使用任何对象,它必须实现两种方法:\输入\和\退出\两种方法__当输入with块时调用enter_uu,当出于任何原因退出块时调用_uEXIT_u


当然,对象在其uuu enter uuu方法中所做的事情取决于它。由于我没有Kivy代码,我只能猜测它的画布。uuu enter_uuu方法在某个地方设置了一个全局变量,该矩形检查该全局变量以查看它应该绘制在哪里。

我不知道Kivy,但我想我可以猜出这个特定的构造是如何工作的

with语句不是保留与canvas?交互的对象的句柄,而是编程将其存储在某个全局变量中,对您隐藏。然后,内部使用的语句使用该全局变量来检索对象。在块的末尾,全局变量作为清理的一部分被清除

其结果是一种折衷:代码不太明确,这通常是Python所希望的特性。然而,代码较短,假设读者知道Kivy是如何工作的,这可能会导致更容易理解。这实际上是用Python制作嵌入式DSL的技术之一


其中涉及一些技术问题。例如,如果您希望能够嵌套这样的构造,将一个与另一个放在一起,而不是简单的全局变量,那么您可能希望使用一个全局变量来保存这样的对象堆栈。此外,如果需要处理线程,可以使用线程局部变量而不是全局变量。但是通用的机制仍然是相同的,Kivy使用了一些状态,这些状态被保存在您直接控制之外的地方。

你们都给了我一个补充的答案。正如你所说,退出和进入是,全局变量是,但是@liori对堆栈的解释非常准确,这也解决了我未来关于简单全局变量存在性的问题,尽管他在几秒钟内是第一个。但是谢谢你。@toto_tico:事实上,我的第一次领先了6秒钟;然而,Liori编辑了他的答案,给出了一个更完整的图片。老实说,我对高知名度用户的快速回答感到非常荣幸。特别是在收到风滚草徽章后。谢谢。当我想到某个全局变量时,你非常准确地指出了它的存在解决了我的问题。谢谢你!
class MyWidget(Widget)
    ... some code 

    def some_method (self):
        with self.canvas as c:
           c.add (Rectangle(pos=self.pos, size=self.size))