RIIA in Python 2.5 alpha: "with... as"

A

Alexander Myodov

Hello,

Having heard that Python 2.5 offers some kind of RIIA concept via
PEP343, got it downloaded (Windows version) and tried. But it did not
work as expected and as wanted.
For the time since I first learned Python, the only reason why I just
could not use it was inability to localize the lifetime of some
variables inside some syntactical "blocks", especially ones in
"for"/"while"/"if" statements, but possibly in any "manually
generated" block (say, like if I would create a "{}" block in C/C++
just to separate one part of the function from another). I mean the
cases like
for k in a1:
pass
print "k: %s" % k
where "k" lives long after the actual need in it was lost, and even
list comprehensions:
b1 = [l for l in a1]
print "l: %s" % l
..

So, with 2.5, I tried to utilize "with...as" construct for this, but
unsuccessfully:
from __future__ import with_statement
with 5 as k:
pass
print k
- told me that "AttributeError: 'int' object has no attribute
'__context__'".


So, does this mean that we still don't have any kind of RIIA in
Python, any capability to localize the lifetime of variables on a
level less than a function, and this is indeed not gonna happen to
change yet?
 
D

Duncan Booth

Alexander said:
So, with 2.5, I tried to utilize "with...as" construct for this, but
unsuccessfully:
from __future__ import with_statement
with 5 as k:
pass
print k
- told me that "AttributeError: 'int' object has no attribute
'__context__'".


So, does this mean that we still don't have any kind of RIIA in
Python, any capability to localize the lifetime of variables on a
level less than a function, and this is indeed not gonna happen to
change yet?

No, it means that Python 2.5 supports 'resource initialisation is
acquisition', but that has nothing to do with the restricting the lifetime
of a variable. You have to use a context manager to handle the resource, 5
isn't a context manager. Some objects which actually need handling as a
resource can be used as context managers, for others you might need to
write your own.

with open('/etc/passwd', 'r') as f:
for line in f:
print line

after executing this f has been closed, but the variable f still exists.

Or try this:
.... def silly(n):
.... print "starting to use", n
.... yield n
.... print "finished with", n
........ print "hello"
....
starting to use 5
hello
finished with 55

The resource is controlled by the with statement, but the scope of the
variable and the lifetime of the object are separate issues.
 
A

Alexander Myodov

Hello Duncan,
No, it means that Python 2.5 supports 'resource initialisation is
acquisition', but that has nothing to do with the restricting the lifetime
of a variable.
Sorry, I misworded the question - RIIA is indeed present at least by
the reason that the examples from PEP pass. Agree, my problem is a bit
different, and I a bit mixed up initialization/acquisition with
lifetime blocks. So, seems that we indeed have one and still don't
have another.
Or maybe you have an idea how this can be fixed? The
simplest way I see is putting all the "controlled" variables into a
dedicated class... and do that each time for each block of variables I
need control lifetime. Is there any simpler way?
 
D

Diez B. Roggisch

No, it means that Python 2.5 supports 'resource initialisation is
Sorry, I misworded the question - RIIA is indeed present at least by
the reason that the examples from PEP pass. Agree, my problem is a bit
different, and I a bit mixed up initialization/acquisition with
lifetime blocks. So, seems that we indeed have one and still don't
have another.
Or maybe you have an idea how this can be fixed? The
simplest way I see is putting all the "controlled" variables into a
dedicated class... and do that each time for each block of variables I
need control lifetime. Is there any simpler way?

Wouldn't a small surrounding function suffice? Something like this
(untested):


def whatever():
def anon():
with open('/etc/passwd', 'r') as f:
for line in f:
print line

Sure, not the nicest of all solutions. But if you really fear that f is
reused, it might help.

Diez
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Alexander said:
Sorry, I misworded the question - RIIA is indeed present at least by
the reason that the examples from PEP pass. Agree, my problem is a bit
different, and I a bit mixed up initialization/acquisition with
lifetime blocks. So, seems that we indeed have one and still don't
have another.
Or maybe you have an idea how this can be fixed?

Why do you want to restrict the lifetime of a variable?

If you want the variable to become unassigned, just invoke the del
statement.

Regards,
Martin
 
D

Duncan Booth

Alexander said:
Or maybe you have an idea how this can be fixed? The
simplest way I see is putting all the "controlled" variables into a
dedicated class... and do that each time for each block of variables I
need control lifetime. Is there any simpler way?

I wouldn't use the word "fixed", but I suppose if you must you could do
something like:
def controlled(**kw):
class Bunch: pass
obj = Bunch()
obj.__dict__.update(kw)
yield obj
obj.__dict__ = {}

with controlled(a=5, b=[1, 2, 3]) as k:
print k.a, k.b, dir(k)


5 [1, 2, 3] ['__doc__', '__module__', 'a', 'b']['__doc__', '__module__']

So the lifetime of the variable is still not limited, but the lifetime of
its attributes is. I still don't see what that buys you though.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top