how does `with canvas:` (Python `with something() as x:`) works implicitly in Kivy?

前端 未结 2 895
孤城傲影
孤城傲影 2021-01-18 08:14

I just realized there is something mysterious (at least for me) in the way you can add vertex instructions in Kivy with the with Python statement. For example,

相关标签:
2条回答
  • 2021-01-18 08:47

    There is nothing extra magical with the with statement, but perhaps you are unaware of how it works?

    In order for any object to be used in a with statement it must implement two methods: __enter__ and __exit__. __enter__ is called when the with block is entered, and __exit__ is called when the block is exited for any reason.

    What the object does in its __enter__ method is, of course, up to it. Since I don't have the Kivy code I can only guess that its canvas.__enter__ method sets a global variable somewhere, and that Rectangle checks that global to see where it should be drawing.

    0 讨论(0)
  • 2021-01-18 08:48

    I don't know Kivy, but I think I can guess how this specific construction work.

    Instead of keeping a handle to the object you are interacting with (the canvas?), the with statement is programmed to store it in some global variable, hidden to you. Then, the statements you use inside with use that global variable to retrieve the object. At the end of the block, the global variable is cleared as part of cleanup.

    The result is a trade-off: code is less explicit (which is usually a desired feature in Python). However, the code is shorter, which might lead to easier understanding (with the assumption that the reader knows how Kivy works). This is actually one of the techniques of making embedded DSLs in Python.

    There are some technicalities involved. For example, if you want to be able to nest such constructions (put one with inside another), instead of a simple global variable you would want to use a global variable that keeps a stack of such objects. Also, if you need to deal with threading, you would use a thread-local variable instead of a global one. But the generic mechanism is still the same—Kivy uses some state which is kept in a place outside your direct control.

    0 讨论(0)
提交回复
热议问题