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

Steven D'Aprano steve at pearwood.info
Sat Jun 14 10:16:17 CEST 2008


On 2008年6月14日 04:19:30 pm Cesare Di Mauro wrote:
> 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.

I am a great fan of Pascal-style with blocks, and I'd love Python to get 
something like them. But I have concluded that they simply aren't 
practical in Python. Your suggestion sounds reasonable at first glance, 
but it isn't really.
def foo(a):
 on a:
 x = round(x, n)
 return x
What does this function do? There's no way of telling, because it 
depends on what attributes a has. It might be equivalent to any of:
a.x = a.round(a.x, a.n) # all attributes
a.x = round(a.x, a.n) # built-in function round
a.x = round(x, a.n) # global x and attribute n
etc.
and there's no way of predicting which it will be until you know what 
attributes a has. Even something like this can fail unexpectedly:
on a:
 import math
 y = math.sin(x)
if object a happens to have an attribute called 'math'.
> Assignament must work on the object's namespace, of course:

There's no "of course" about it. That rule implies that it is impossible 
to modify the local namespace inside an 'on block', because the 
object's namespace will always take priority:
def foo(a):
 y = 1
 on a:
 y = x + 1 # creates a new a.y attribute!
 return y # always returns 1
Perhaps you want this behaviour, but I don't think it is either obvious 
or desirable.
Pascal doesn't have this problem because you always explicitly define 
your local variables.
-- 
Steven


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /