Python "with"

J. Cliff Dyer jcd at sdf.lonestar.org
Sun Sep 16 22:52:48 CEST 2007


Ivan Voras wrote:
> Hi,
>
> I'm looking for a construct that's similar to (Turbo) Pascal's "with"
> statement. I read about the Python's new "with" statement, but I was
> dissapointed to learn that it does something different (I still don't
> see how it's better than try..except..finally, but that's not my question).
>
> Is there something similar to what I want that's Pythonic enough?
>
> (If you're not familiar with Pascal, here's how it works:
>
> with some.big.structure.or.nested.objects.element do begin
>      member1 := something;
>      member2 := something;
> end;
>
> which exactly translates to this equivalent:
>
> some.big.structure.or.nested.objects.element.member1 := something;
> some.big.structure.or.nested.objects.element.member2 := something;
>
> i.e. it's a wrist-saver. I think a similar feature exists in C99, for
> structs.
>
> I know it can be almost always done by using a temporary variable:
>
> tmp = some.big.structure.or.nested.objects.element
> tmp.member1 = something
> tmp.member2 = something
>   
You can import the members directly, using:

>>> from some.big.structure.or.nested.objects.element import member1,
member2

which requires you to know the variable names.  But if you want to do it
after the import, your tmp example is the way to go.  It would be less
ugly if your variable is named so that it still has some connection to
the purpose of the module.

There are other options, too:

>>> import some.big.structure.or.nested.objects.element as tmp

This will still make you prefix tmp to the variables, but you don't need
a separate statement devoted to rebinding the module to a new name. 

Personally, I don't find the shorter prefix all that ugly.  For me
ugliness and clarity are almost entirely synonymous when it comes to
code, so maintaining the certainty about where the variables came from
is a good thing.  I've just started a job where I have to maintain perl
code, so I keep running across things like

use File::Basename;
my $dir = dirname($fullpath);

and I keep wondering where basename came from.  Is it a builtin?  Was it
from File::  A prefix, no matter how short, how obscure, how
undescriptive, will let you trace exactly where each name came from. 
Which I find deeply beautiful.  All you have to do is look up the page,
and it's there somewhere.  You *can* do the same with Perl, but it's
actually discouraged by the structure of the language.  In other words,
the simplest case does the wrong thing.

Python does allow you to import all names from a module, unprefixed but
it leads you into the same ugliness and namespace clobbering that you
get with Perl, so I'm not going to tell you how to do it.

I think the 'import long.name as short' syntax will help your wrists the
most while still retaining the clarity of explicit module referencing. 
And you won't have the extraneous assignment (tmp = long.name)
cluttering up your code.

Cheers,
Cliff



More information about the Python-list mailing list