[Python-Dev] Python FAQ: Why doesn't Python have a "with" statement?

Cesare Di Mauro cesare at pronto.it
Sat Jun 14 08:19:30 CEST 2008


I agree: Python's with statement does have a completely different meaning of the same Pascal & Co 's statement.

However, I don't agree with the FAQ on this point. I think that a Pascal-like with statement can be achieved, even with a dynamic language such as Python, and in a simple way.

We know that name resolution in Python uses the LEGB rule: first it starts looking at locals, then to enclosing functions, then to globals, and finally to the built-ins.
Assignament usually acts on locals (and with global statement, we can can even change globals).

A "with" statement (such as Pascal's one) can be implemented adding a new scope resolution on top of LEGB. So, taking the FAQ's example, and using a new keyword (because with is already assigned to a different kind of work):

def foo(a):
  on a:
     print x

the block defined by the "on" statement first must starts looking at the object's namespace. If no symbol was defined inside a, then it follows the traditional LEGB name resolution.

Assignament must work on the object's namespace, of course:

def foo(a):
  on a:
     x += 1
     print x
    will be equivalent to:

def foo(a):
  a.x += 1
  print a.x

A more complex example (taking "A Simple Hello World Program" in http://docs.python.org/lib/node688.html ) will show a major benefit on using this statement:

from Tkinter import *

class Application(Frame):
   def say_hi(self):
       print "hi there, everyone!"

   def createWidgets(self):
       on Button(self):
           text = "QUIT"
           fg = "red"
           command = self.quit

           pack({"side": "left"})

       on Button(self):
           text = "Hello",
           command = self.say_hi

           pack({"side": "left"})

   def __init__(self, master=None):
       Frame.__init__(self, master)
       self.pack()
       self.createWidgets()

root = Tk()
on Application(master=root):
   mainloop()
root.destroy()


Notice that adding a new step in scope resolution doesn't necessarily increase execution speed. Taking a look at the above example, accessing to the Button instance's attributes can be as fast as the original example, if not better.

Also, the new step in scope resolution will be needed only inside the block defined by the "on" statement. Outside the "on" statement, the usual LEGB method will be used.

Obviously "on" statements can be nested, adding each one a new step on scope resolution.

IMO such kind of statement can be very useful to make the source code more readable, especially working with GUIs.

If somebody knows SmallTalk, it looks similar to the "cascade messages" syntax:

(Window new)
   label: 'Hello';
   open

Cesare Di Mauro

In data 14 giugno 2008 alle ore 00:42:52, Michael Foord <fuzzyman at voidspace.org.uk> ha scritto:

> The Python FAQ has the following entry:
>
> 4.26   Why doesn't Python have a "with" statement like some other languages?
>
> From:
>
> http://www.python.org/doc/faq/general/
>
> Even if the content is still relevant (I know nothing of the use of
> 'with' outside Python), the entry probably needs at least clarifying now
> that Python does have a 'with' statement.
>
> Michael Foord
>




More information about the Python-Dev mailing list