我只是意识到在使用with
Python语句在Kivy中添加顶点指令的方式中有一些神秘的东西(至少对我而言).例如,使用的方式with
是这样的:
... some code
class MyWidget(Widget)
... some code
def some_method (self):
with self.canvas:
Rectangle(pos=self.pos, size=self.size)
Run Code Online (Sandbox Code Playgroud)
一开始我认为这只是with
偶尔使用的Python语句.但我突然意识到事实并非如此.通常它看起来更像这样(从这里取的例子):
with open('output.txt', 'w') as f:
f.write('Hi there!')
Run Code Online (Sandbox Code Playgroud)
as
实例之后通常会有一个类似于对象的别名.在Kivy示例中,我们没有定义和别名哪个仍然可以.但困扰我的部分是指令Rectangle仍然与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))
Run Code Online (Sandbox Code Playgroud)
我假设在内部方法add
是被调用的方法.假设我们可以简单地添加矩形self.add (Rectangle(pos=self.pos, size=self.size))
我错过了关于with
Python语句的一些内容吗?或者这是Kivy实施的某种方式?
我不知道Kivy,但我想我能猜出这个具体的建筑是如何工作的.
而不是保持与您正在交互的对象(画布?)的句柄,该with
语句被编程为将其存储在一些隐藏给您的全局变量中.然后,您在内部with
使用的语句使用该全局变量来检索该对象.在块结束时,全局变量将作为清理的一部分被清除.
结果是权衡:代码不那么明确(这通常是Python中所需的特性).但是,代码更短,这可能会导致更容易理解(假设读者知道Kivy如何工作).这实际上是用Python制作嵌入式DSL的技术之一.
涉及一些技术细节.例如,如果您希望能够嵌套此类构造(将一个构造放在with
另一个构造中),而不是简单的全局变量,则需要使用保留此类对象堆栈的全局变量.此外,如果您需要处理线程,则可以使用线程局部变量而不是全局变量.但是通用机制仍然是相同的 - 基维使用了一些保存在你直接控制范围之外的状态.
归档时间: |
|
查看次数: |
566 次 |
最近记录: |