Re: Creating a local variable scope.

2009-12-09 Thread rwwh
On Nov 30, 1:26 am, markolopa  wrote:

> I would be much happier with the smaller namespace. To fix the code
> that you show I would impose
>
> s = None
> while True:
>      s = raw_input("enter something: ")
>      if s not in ('q', 'quit', 'exit'): break
> print s

So you propose: if the variable exists in a wider scope, you ideal
python would not create it in an inner scope. How is this helping your
original case?

I remind you:

class ValueColumn(AbstractColumn):
def __init__(self, name, header, domain_names):
if type(domain_names) != tuple:
raise ValueError('blub')
for name in domain_names:
if type(name) != str:
raise ValueError('blub')
self.domain_names = domain_names
super(ValueColumn, self).__init__(name, header)

When "for name" is reached, "name" already exists and no local
variable would be created. How does this help you?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-12-03 Thread Ben Finney
Lie Ryan  writes:

> On 12/2/2009 2:56 PM, Ben Finney wrote:
> > The ‘camelCase’ form is not conformant with PEP 8 at all (which makes me
> > glad, since it's hideous).
>
> For some reason, every time I look at a unittest code, I was thinking
> of Java... and not just because it's modeled after JUnitTest.

Right, there are a number of standard library modules that don't conform
to PEP 8; in many cases that's because the module in question was
largely written before PEP 8.

-- 
 \ “When we pray to God we must be seeking nothing — nothing.” |
  `\  —Saint Francis of Assisi |
_o__)  |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-12-03 Thread Lie Ryan

On 12/2/2009 2:56 PM, Ben Finney wrote:

The ‘camelCase’ form is not conformant with PEP 8 at all (which makes me
glad, since it's hideous).


For some reason, every time I look at a unittest code, I was thinking of 
Java... and not just because it's modeled after JUnitTest.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-12-02 Thread r0g
Ben Finney wrote:
> markolopa  writes:
> 
>> Hi Roger,
>>
> […]
>>> Long, descriptive variable names all_in_lower_case
>>> Function names all in CamelCase
>>> Global names are in ALL CAPS
>> yes, pep8 I guess.
> 
> Not quite: it deviates from PEP 8 on function names, which should rather
> be ‘lower_case_words_separated_by_underscores’.
> 
> The ‘UPPER_CASE_WORDS_WITH_UNDERSCORES’ form is for “constants”, i.e.
> names that indicate they should stay bound to the same value through the
> life of the program (which is the closest normal Python programs get to
> a “constant” binding).
> 
> The ‘TitleCase’ form should be used only for class names.
> 
> The ‘camelCase’ form is not conformant with PEP 8 at all (which makes me
> glad, since it's hideous).
> 


Heh, see! It's a spiky subject ;) Someday I'm going to found a
substantial open source project just so I can force subsequent
contributors to format their code the way I like it! *bwahahahaaa* :)


Roger.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-12-01 Thread Ben Finney
markolopa  writes:

> Hi Roger,
>
[…]
> > Long, descriptive variable names all_in_lower_case
> > Function names all in CamelCase
> > Global names are in ALL CAPS
>
> yes, pep8 I guess.

Not quite: it deviates from PEP 8 on function names, which should rather
be ‘lower_case_words_separated_by_underscores’.

The ‘UPPER_CASE_WORDS_WITH_UNDERSCORES’ form is for “constants”, i.e.
names that indicate they should stay bound to the same value through the
life of the program (which is the closest normal Python programs get to
a “constant” binding).

The ‘TitleCase’ form should be used only for class names.

The ‘camelCase’ form is not conformant with PEP 8 at all (which makes me
glad, since it's hideous).

-- 
 \  “I see little commercial potential for the Internet for at |
  `\   least ten years.” —Bill Gates, 1994 |
_o__)  |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-12-01 Thread markolopa
Hi Roger,

> > That is what I do regularly...8->
>
> Well really dude, you need to stop doing that. It's not a language
> problem, it's a memory problem (human not RAM!).

You guessed quite correctly!...:-) I can't recognise my code sometimes
after a single week. That's why I spend a lot of time cleaning it to
be easy to get back. Fortunately it seems to be recognised as a good
practice...

> You need to be aware of
> what you're putting into your namespace. This is one of the reasons
> people try to avoid using global variables, if you forget you've used a 
> variable name and use it again somewhere you get an undefined state and
> hours of debugging / data loss / subtle corruptions you won't spot until
>  the backups have all been cycled etc.

Sure, zero global variables in my programs.

> I'm surprised you have a recurring problem with this really. My memory
> is terrible and I reuse variable names all over the place without any
> trouble. Maybe try keeping the length of your functions down so that
> they fit on a single screen and create and use a strong naming
> convention i.e.
>
> Long, descriptive variable names all_in_lower_case
> Function names all in CamelCase
> Global names are in ALL CAPS

yes, pep8 I guess.

> Loop variable names all prefixed with 'each_'

Interesting. A radical idea (and not very elegant for my taste I would
say) but it could certainly make me avoid such bugs...

Cheers!
Marko
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-12-01 Thread markolopa
Hi Dave,

Since you feel like discussing my weird idea of Python reform :-) lets
go...

On 30 Nov, 11:29, Dave Angel  wrote:
> Somehow you seem to think there's some syntax for "creating" avariable.  In 
> fact, what's happening is you're binding/rebinding a name
> to an object.  And if you forbid doing this inside the loop, for names
> that exist outside the loop, then most of the useful work the loop does
> becomes impossible.  Remember, in Python, there's no declaration of 
> avariable(except the global statement, which does it sort-of).

You are right, I have not used precise terms. Let's use examples then.

> So you'd
> be disallowing the following:
>
>     counter = 5
>     for item in itemlist:
>            if item > 19:
>                 counter = counter + 5

In this example, I would allow the expected behaviour. Since "counter"
was bound in the outer loop, the new binding got in the inner loop
would persist after the end of the "if" and the "for" block.

Other examples:

if True:
   a = 5
print a

would produce an error while

a = 3
if True:
a = 5
print a

would print 5 (and not 3).

But now I realise that one of my bugs wouldn't be solved, so I believe
you have managed to convince me that my idea does not make much
sense...:-)

> The only way I can think you possibly want this is if you're just
> referring to "loop variables", such as "item" in the above example.  The
> problem is that on many loops, for example a "while" loop, there's no
> such thing.

This would already be great. I believe that most bugs I've had related
to this issue are due to accidental reuse of loop variables. But
treating the loop variables as a special case is perhaps not very
elegant.

Greetings,
Marko
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread r0g
markolopa wrote:
> On Nov 30, 4:46 am, Dave Angel  wrote:
>> markolopa wrote:

>> or
>> whether you accidentally reused the same name without giving it a new
>> value in the new loop.  
> 
> That is what I do regularly...8->
> 



Well really dude, you need to stop doing that. It's not a language
problem, it's a memory problem (human not RAM!). You need to be aware of
what you're putting into your namespace. This is one of the reasons
people try to avoid using global variables, if you forget you've used a
variable name and use it again somewhere you get an undefined state and
hours of debugging / data loss / subtle corruptions you won't spot until
 the backups have all been cycled etc.

I'm surprised you have a recurring problem with this really. My memory
is terrible and I reuse variable names all over the place without any
trouble. Maybe try keeping the length of your functions down so that
they fit on a single screen and create and use a strong naming
convention i.e.

Long, descriptive variable names all_in_lower_case
Function names all in CamelCase
Global names are in ALL CAPS
Loop variable names all prefixed with 'each_'

The details don't so much matter as long as you are consistent with it.
I'm sure many here would hate my coding conventions if they had to use
them but they seem to work OK for me and I can't recall ever having this
problem.


Roger.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread Alf P. Steinbach

* Jean-Michel Pichavant:

Steven D'Aprano wrote:

On Mon, 30 Nov 2009 02:11:12 +0100, Alf P. Steinbach wrote:

 

I think if one could somehow declare names as const (final, readonly,
whatever) then that would cover the above plus much more.



Having real constants is one feature that I miss. Because Python 
doesn't have constants, I find I've lost the discipline to avoid 
"magic numbers" (and strings) in my code.



  
I don't get you, this can be easily avoid with a strong naming 
convention. I mean, despite they are not really constants, you can still 
use variables to name your numbers and string, to give the reader a 
usefull hint on the meaning of your code. Yet it is still a matter of 
discipline, it is sometimes very tempting to put the string directly 
(unlike numbers string can be meaningful sometimes)


It may be surprising how many things turn out to be readonly.

Consider the OP's code:



class ValueColumn(AbstractColumn):
def __init__(self, name, header, domain_names):
if type(domain_names) != tuple:
raise ValueError('a tuple of domain names must be given')
for name in domain_names:
if type(name) != str:
raise ValueError('a tuple of domain names must be given')
self.domain_names = domain_names
super(ValueColumn, self).__init__(name, header)



Here the arguments should ideally be read only names, which would have cought 
the bug of reusing 'name' in the for loop.


But you really wouldn't code this as



class ValueColumn(AbstractColumn):
def __init__(SELF, NAME, HEADER, DOMAIN_NAMES):
if type(DOMAIN_NAMES) != tuple:
raise ValueError('a tuple of domain names must be given')
for name in DOMAIN_NAMES:
# Argh, at this point 'name' is readonly, but cannot express that.
if type(name) != str:
raise ValueError('a tuple of domain names must be given')
SELF.domain_names = domain_names
super(ValueColumn, SELF).__init__(NAME, HEADER)



Or, at least I wouldn't do that.

It's ugly.

And you have to /change the names/ as the readonly-ness changes.


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread Jean-Michel Pichavant

Steven D'Aprano wrote:

On Mon, 30 Nov 2009 02:11:12 +0100, Alf P. Steinbach wrote:

  

I think if one could somehow declare names as const (final, readonly,
whatever) then that would cover the above plus much more.



Having real constants is one feature that I miss. Because Python doesn't 
have constants, I find I've lost the discipline to avoid "magic 
numbers" (and strings) in my code.



  
I don't get you, this can be easily avoid with a strong naming 
convention. I mean, despite they are not really constants, you can still 
use variables to name your numbers and string, to give the reader a 
usefull hint on the meaning of your code. Yet it is still a matter of 
discipline, it is sometimes very tempting to put the string directly 
(unlike numbers string can be meaningful sometimes)


JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread Steven D'Aprano
On Mon, 30 Nov 2009 02:11:12 +0100, Alf P. Steinbach wrote:

> I think if one could somehow declare names as const (final, readonly,
> whatever) then that would cover the above plus much more.

Having real constants is one feature that I miss. Because Python doesn't 
have constants, I find I've lost the discipline to avoid "magic 
numbers" (and strings) in my code.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread Dave Angel

markolopa wrote:

On Nov 30, 4:46 am, Dave Angel  wrote:
  

markolopa wrote:


Antoher 15 minutes lost because of that Python "feature"... Is it only
me???
  

Yep, I think so.



Not very consoling but thanks anyway!...:-

  

 You're proposing a much more complex scoping rule,
where if a variable already exists before entering a loop, then the loop
uses that existing variable, but if not, it creates its own local one
and destroys it when exiting the loop.



Alternatively you could forbid the creation of a variable in a inner
block if it already exists. 
Somehow you seem to think there's some syntax for "creating" a 
variable.  In fact, what's happening is you're binding/rebinding a name 
to an object.  And if you forbid doing this inside the loop, for names 
that exist outside the loop, then most of the useful work the loop does 
becomes impossible.  Remember, in Python, there's no declaration of a 
variable (except the global statement, which does it sort-of).  So you'd 
be disallowing the following:


   counter = 5
   for item in itemlist:
  if item > 19:
   counter = counter + 5

The only way I can think you possibly want this is if you're just 
referring to "loop variables", such as "item" in the above example.  The 
problem is that on many loops, for example a "while" loop, there's no 
such thing.



Either that or forbid the usage of the
variable in an outter block later if it exists both in an inner and
outer block.

  
You need to define "exists" in order to make discussion unambiguous.  
Without extra declarations of some type, I can't believe there's any way 
to make any variation of this concept work in the general case.

Aren't there languages that forbid the declarations of variables in a
function with the same name as global variables? I know that this is
an extreme defensive measure, but I have to say that I like it.
Allowing to create a new variable when a variable with the same name
is already exists in the namespace makes for harm that good, for me at
least. Of course this issue is much broader than the one I proposed
initially.

  
I can't think of any, among the 35 languages I've programmed in 
professionally over the years.  All right, to be fair, about half of 
those were assembly languages at various levels.  And I don't believe I 
worked in any assembly language that even had separate scoping for 
functions.


DaveA


--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread Lie Ryan

On 11/30/2009 8:13 PM, markolopa wrote:

On Nov 30, 4:46 am, Dave Angel  wrote:

markolopa wrote:

Antoher 15 minutes lost because of that Python "feature"... Is it only
me???


Yep, I think so.


Not very consoling but thanks anyway!...:-


  You're proposing a much more complex scoping rule,
where if a variable already exists before entering a loop, then the loop
uses that existing variable, but if not, it creates its own local one
and destroys it when exiting the loop.


Alternatively you could forbid the creation of a variable in a inner
block if it already exists. Either that or forbid the usage of the
variable in an outter block later if it exists both in an inner and
outer block.



Of course, the best solution would be to allow assignment only in a 
single line of source of code. Reassignment by different lines of code 
would be a syntax error. You're forced to have different names if you 
want assign something multiple times. That way, no bugs is possible.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread markolopa
On Nov 30, 4:46 am, Dave Angel  wrote:
> markolopa wrote:
> > Antoher 15 minutes lost because of that Python "feature"... Is it only
> > me???
>
> Yep, I think so.

Not very consoling but thanks anyway!...:-

> You're proposing a much more complex scoping rule,
> where if a variable already exists before entering a loop, then the loop
> uses that existing variable, but if not, it creates its own local one
> and destroys it when exiting the loop.

Alternatively you could forbid the creation of a variable in a inner
block if it already exists. Either that or forbid the usage of the
variable in an outter block later if it exists both in an inner and
outer block.

Aren't there languages that forbid the declarations of variables in a
function with the same name as global variables? I know that this is
an extreme defensive measure, but I have to say that I like it.
Allowing to create a new variable when a variable with the same name
is already exists in the namespace makes for harm that good, for me at
least. Of course this issue is much broader than the one I proposed
initially.

> I think if you had your wish, you'd find that you had more exceptions
> where you had to pre-declare things, than the times when you avoided the
> bugs you describe.  

You are probably right, otherwise Guido would have done what I
suggest... but I really don't see why.

> I don't like languages that make me write extra
> stuff 100 times, to save one instance of extra debugging.  If Python
> already required declarations, then I might buy your arguments.  But it
> wouldn't be Python.

My guess is that if the change I propose was implemented, the number
additional lines that would be needed to make the present python code
work would be 1 in a thousand or less. Of course I may be wrong...
Besides this additional line can make the code more readable,
strassing the fact that the variable inside the block actually
"belongs" to outside.

> In your particular case, the compiler couldn't guess whether you used
> the first loop to decide which domain to use in the second loop,

That is what I wish the compiler should forbid...:->

> or
> whether you accidentally reused the same name without giving it a new
> value in the new loop.  

That is what I do regularly...8->

> If you need to use the same name, you could
> always follow your loops with the del statement to invalidate the name.

Several people have suggested explicit destruction of the variables I
don't need. Python allows it but of course this does not solve my
problem. It does not make sense to use such a clean language as Python
and regularly delete all variables used inside the blocks when leaving
it. And of course the bug comes because I have no idea that I am using
the same name again.

Cheers!
Marko
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread markolopa
Hi Steve!

On Nov 30, 1:46 am, Steve Howell  wrote:
> I occasionally make the error you make, but I think the real problem
> you are having is lack of attention to detail.  If name collisions are
> a common problem for you, consider writing shorter methods

Yes, this could be a solution, though I believe that too many (sub)
methods called by a single method turn the code less readable.

> or develop
> the habit of using more descriptive variable names.

Also a good suggestion. Alternatively I have considered to do the
opposite, to use weird (the opposite of descriptive) names for
variables that should exist only inside the block, in order to
differentiate them from the variables that should persist.

>  In the code
> above, you could have easily cleaned up the namespace by extracting a
> method called get_arg_columns().  Having to spend 15 minutes tracking
> down a bug usually indicates that you are not being systematic in your
> thinking.  If you are rushing too much, slow down.  If you are tired,
> take a break.  If you make the same mistake twice, commit to yourself
> not to make it a third time.  Also, test your methods one at a time
> and get them rock solid before writing more code.

Nice suggestions thanks, all of them apply to me!...:-) Compared to
the normal coder I have a strong tendency to loose myself in details.
That is why I have to be very systematic, write lots of defensive code
(to catch the bugs as soon as possible), write unit tests (great habit
I've developped recently!). Python is fantastic for those goals. The
only laking feature I find is really the survival of variables, a
problem that does not exist in C++ or in Perl (with use strict).
Besides this kind of bug I have noticed only 2 other sources of bug I
had more than once with python code.
- expecting float from integer division (easily avoidable, either with
3.0 or from __future__...)
- expecting diferent objects in a list have having the same several
times (deepcopy issue, also easily avoidable once we know it)

So my only other problem is with this "survival" feature. I consider
to write my own version of Python, the one that would not allow the
usage of varaibles outside the block it was created. Of course I won't
rewrite CPython but I could add an error (or warning) to pylint. With
some luck it already exists, I will investigate...

Greets!
Marko
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread Terry Reedy

markolopa wrote:



so "domain" should not exist in my namespace since I have no
information associated to "domain" only to "self.domains". Python
should allow me to write safe code!


Leaving iteration names bound after loop exit is a feature. If you do 
not like it, explicitly unbind it.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread Dave Angel

markolopa wrote:


===

arg_columns =]
for domain in self.domains:
i =elf.get_column_index(column_names, domain.name)
col =olumn_elements[i]
if len(col) !=en(val_column):
ValueError('column %s has not the same size as the value
column %s'
   % (column_names[i], self.name))
arg_columns.append(col)

[...]

value_dict =}
for i, val_str in enumerate(val_column):
arg_name_row =c[i] for c in arg_columns]
args =domain[name] for name in arg_name_row]
value_dict[tuple(args)] =loat(val_str)
repo[self.name] =alue_dict

===

The bug is corrected replacing the line

args =domain[name] for name in arg_name_row]

by

args =domain[name] for name, domain in zip(arg_name_row,
self.domains)]

so "domain" should not exist in my namespace since I have no
information associated to "domain" only to "self.domains". Python
should allow me to write safe code!

Antoher 15 minutes lost because of that Python "feature"... Is it only
me???

  
Yep, I think so.  You're proposing a much more complex scoping rule, 
where if a variable already exists before entering a loop, then the loop 
uses that existing variable, but if not, it creates its own local one 
and destroys it when exiting the loop.  That's the exact opposite of 
what function definitions do, which already makes it confusing.


I think if you had your wish, you'd find that you had more exceptions 
where you had to pre-declare things, than the times when you avoided the 
bugs you describe.  I don't like languages that make me write extra 
stuff 100 times, to save one instance of extra debugging.  If Python 
already required declarations, then I might buy your arguments.  But it 
wouldn't be Python.

Thanks for your comment!
Marko

  


In your particular case, the compiler couldn't guess whether you used 
the first loop to decide which domain to use in the second loop, or 
whether you accidentally reused the same name without giving it a new 
value in the new loop.  If you need to use the same name, you could 
always follow your loops with the del statement to invalidate the name.



DaveA

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread Alf P. Steinbach

* markolopa:


On 18 Sep, 10:36, "markol...@gmail.com"  wrote:

On Sep 11, 7:36 pm, Johan Grönqvist  wrote:

I find several places in my code where I would like tohavea variable
scope that is smaller than the enclosing function/class/module definition.

This is one of the single major frustrations I have with Python and an
important source of bugs for me. Here is a typical situation


Here is another bug that I just got. Twenty minutes lost to find it...

class ValueColumn(AbstractColumn):
def __init__(self, name, header, domain_names):
if type(domain_names) != tuple:
raise ValueError('a tuple of domain names must be given')
for name in domain_names:
if type(name) != str:
raise ValueError('a tuple of domain names must be
given')
self.domain_names = domain_names
super(ValueColumn, self).__init__(name, header)

The upper class was initialized with the wrong name, because the for
loop to check
domain_names used "name" which is also the argument to be passed.

If is an old thread but I am reopening to present real situation where
this Python
"feature" bothers me...


I think if one could somehow declare names as const (final, readonly, whatever) 
then that would cover the above plus much more.



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread Steve Howell
On Nov 29, 4:26 pm, markolopa  wrote:
> Less than 3 hours have passed since my last post and got yet another
> bug that could be prevented if Python had the functionality that other
> languages have to destroy variables when a block ends. Here is the
> code:
>
> =
>
> arg_columns = []
> for domain in self.domains:
>     i = self.get_column_index(column_names, domain.name)
>     col = column_elements[i]
>     if len(col) != len(val_column):
>         ValueError('column %s has not the same size as the value
> column %s'
>                    % (column_names[i], self.name))
>         arg_columns.append(col)
>
> [...]
>
> value_dict = {}
> for i, val_str in enumerate(val_column):
>     arg_name_row = [c[i] for c in arg_columns]
>     args = [domain[name] for name in arg_name_row]
>     value_dict[tuple(args)] = float(val_str)
> repo[self.name] = value_dict
>
> =
>
> The bug is corrected replacing the line
>
>     args = [domain[name] for name in arg_name_row]
>
> by
>
>     args = [domain[name] for name, domain in zip(arg_name_row,
> self.domains)]
>
> so "domain" should not exist in my namespace since I have no
> information associated to "domain" only to "self.domains". Python
> should allow me to write safe code!
>
> Antoher 15 minutes lost because of that Python "feature"... Is it only
> me???
>

I occasionally make the error you make, but I think the real problem
you are having is lack of attention to detail.  If name collisions are
a common problem for you, consider writing shorter methods or develop
the habit of using more descriptive variable names.  In the code
above, you could have easily cleaned up the namespace by extracting a
method called get_arg_columns().  Having to spend 15 minutes tracking
down a bug usually indicates that you are not being systematic in your
thinking.  If you are rushing too much, slow down.  If you are tired,
take a break.  If you make the same mistake twice, commit to yourself
not to make it a third time.  Also, test your methods one at a time
and get them rock solid before writing more code.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread markolopa
Hi Lie!

On Nov 29, 11:11 pm, Lie Ryan  wrote:
> here is another bug you might have if python have an "even-more-local"
> scope:
>
> while True:
>      s = raw_input("enter something: ")
>      if s not in ('q', 'quit', 'exit'): break
> print s
>
> if the while block has become its own namespace; print s would generate
> NameError.

This bug you show is completely different, because it is not
dangerous: you get the error and you realise directly how to fix it.

> It is one or the other, you will have problem caused by "namespace too
> small" or "namespace too big". Neither is better than the other, so
> python's two-level name resolution (global and local level) is the
> simplest one, is the better one.

I would be much happier with the smaller namespace. To fix the code
that you show I would impose

s = None
while True:
 s = raw_input("enter something: ")
 if s not in ('q', 'quit', 'exit'): break
print s

The use in a block of variables created in an inner block is (for me
at least) more an exception than a rule.

Less than 3 hours have passed since my last post and got yet another
bug that could be prevented if Python had the functionality that other
languages have to destroy variables when a block ends. Here is the
code:

=

arg_columns = []
for domain in self.domains:
i = self.get_column_index(column_names, domain.name)
col = column_elements[i]
if len(col) != len(val_column):
ValueError('column %s has not the same size as the value
column %s'
   % (column_names[i], self.name))
arg_columns.append(col)

[...]

value_dict = {}
for i, val_str in enumerate(val_column):
arg_name_row = [c[i] for c in arg_columns]
args = [domain[name] for name in arg_name_row]
value_dict[tuple(args)] = float(val_str)
repo[self.name] = value_dict

=

The bug is corrected replacing the line

args = [domain[name] for name in arg_name_row]

by

args = [domain[name] for name, domain in zip(arg_name_row,
self.domains)]

so "domain" should not exist in my namespace since I have no
information associated to "domain" only to "self.domains". Python
should allow me to write safe code!

Antoher 15 minutes lost because of that Python "feature"... Is it only
me???

Thanks for your comment!
Marko
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread Lie Ryan

On 11/30/2009 8:12 AM, markolopa wrote:

Hi,

On 18 Sep, 10:36, "markol...@gmail.com"  wrote:

On Sep 11, 7:36 pm, Johan Grönqvist  wrote:

I find several places in my code where I would like tohavea variable
scope that is smaller than the enclosing function/class/module definition.


This is one of the single major frustrations I have with Python and an
important source of bugs for me. Here is a typical situation


Here is another bug that I just got. Twenty minutes lost to find it...

class ValueColumn(AbstractColumn):
 def __init__(self, name, header, domain_names):
 if type(domain_names) != tuple:
 raise ValueError('a tuple of domain names must be given')
 for name in domain_names:
 if type(name) != str:
 raise ValueError('a tuple of domain names must be
given')
 self.domain_names = domain_names
 super(ValueColumn, self).__init__(name, header)

The upper class was initialized with the wrong name, because the for
loop to check
domain_names used "name" which is also the argument to be passed.

If is an old thread but I am reopening to present real situation where
this Python
"feature" bothers me...



here is another bug you might have if python have an "even-more-local" 
scope:


while True:
s = raw_input("enter something: ")
if s not in ('q', 'quit', 'exit'): break
print s

if the while block has become its own namespace; print s would generate 
NameError.


It is one or the other, you will have problem caused by "namespace too 
small" or "namespace too big". Neither is better than the other, so 
python's two-level name resolution (global and local level) is the 
simplest one, is the better one.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread markolopa
Hi,

On 18 Sep, 10:36, "markol...@gmail.com"  wrote:
> On Sep 11, 7:36 pm, Johan Grönqvist  wrote:
> > I find several places in my code where I would like tohavea variable
> > scope that is smaller than the enclosing function/class/module definition.
>
> This is one of the single major frustrations I have with Python and an
> important source of bugs for me. Here is a typical situation

Here is another bug that I just got. Twenty minutes lost to find it...

class ValueColumn(AbstractColumn):
def __init__(self, name, header, domain_names):
if type(domain_names) != tuple:
raise ValueError('a tuple of domain names must be given')
for name in domain_names:
if type(name) != str:
raise ValueError('a tuple of domain names must be
given')
self.domain_names = domain_names
super(ValueColumn, self).__init__(name, header)

The upper class was initialized with the wrong name, because the for
loop to check
domain_names used "name" which is also the argument to be passed.

If is an old thread but I am reopening to present real situation where
this Python
"feature" bothers me...

Marko
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-24 Thread Albert van der Horst
In article <65e8a017-abcb-49ad-8867-bc473f83e...@s39g2000yqj.googlegroups.com>,
Bearophile   wrote:
>Steven D'Aprano:
>
>> (3) Create an inner function, then call that.
>
>Several people after someone gives this anwer.
>
>
>> My personal opinion is that if you really need a local scope
>> inside a function, the function is doing too much and should be split up.
>
>I agree. And a way to split a function is to define an inner function,
>that's one of their main purposes. No need to add other things to the
>language as the OP suggests.

There are exceptions. E.g. implementations of quicksort have a
recursive inner function, that you may prefer to not have exposed.
Also there may be data to communicate to or between instances of
the inner function.

At least that is the situation in most languages. I would be
interested to learn if and how Python gets around that.

>
>Bye,
>bearophile

Groetjes Albert

--
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
alb...@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-19 Thread Ethan Furman

Dave Angel wrote:

Johan Grönqvist wrote:

DiZazzo skrev:


I would do something like this:


class Namespace(object):


... pass
...


n = Namespace()
n.f = 2
n.g = 4
print f


Traceback (most recent call last):
  File "", line 1, in ?
NameError: name 'f' is not defined


print n.f


2



I like this solution. This also minimizes the extra code if I would 
want to explicitly delete the bindings, as I would only need one line 
to delete the Namespace object.


Even simpler solution for most cases, use longer names.  If the name 
means something in the local context, and the next context is different, 
you presumably will use a deliberately different name.  In your earlier 
example, if you called them row and column, you ought to notice if you 
used row instead of column in the later "scope".


One thing people don't notice when they ask the compiler to catch all 
these types of problems is that there are lots of things the compiler 
can't check.


Well said.  One of the things I *love* about Python is that it doesn't 
try to do my programming for me.  For the mistakes we inevitably make, 
good test suites are incredibly useful.


Still, and just for fun, the following is at least mildly entertaining 
(but then, I am easily amused :)


class micro_scope(object):
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if type is value is traceback is None:
self.__dict__.clear()

with micro_scope() as m:
m.this = 'that'
m.value = 89
for m.i in range(10):
do_something_with(m.i)

m.value
#exception raised here, as m.value no longer exists

Don't worry, Steven, I'll never actually use that!  ;-)

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-19 Thread Dave Angel

Johan Grönqvist wrote:
Sean 
DiZazzo skrev:

I would do something like this:


class Namespace(object):

... pass
...

n = Namespace()
n.f = 2
n.g = 4
print f

Traceback (most recent call last):
  File "", line 1, in ?
NameError: name 'f' is not defined

print n.f

2


I like this solution. This also minimizes the extra code if I would 
want to explicitly delete the bindings, as I would only need one line 
to delete the Namespace object.


Thanks!

Johan




Even simpler solution for most cases, use longer names.  If the name 
means something in the local context, and the next context is different, 
you presumably will use a deliberately different name.  In your earlier 
example, if you called them row and column, you ought to notice if you 
used row instead of column in the later "scope".


One thing people don't notice when they ask the compiler to catch all 
these types of problems is that there are lots of things the compiler 
can't check.  In Python if you delete a previous attribute, you'll get 
an error when trying to read that attribute, but not when trying to 
write it.  Because as soon as you write it, you're declaring it again.


I spent years in C++ and Java environments, as well as many other 
languages that enforced some of these rules.  But once you get used to 
the notion that the system won't check you, you're less likely to fall 
into the traps that always remain in those other languages -- write your 
own code defensively.  And that means that for anything bigger than 
throw-away samples, use real names for things.,


I spent time years ago in Forth, where a name could be almost anything 
(no embedded spaces), and where syntax in the language was almost 
non-existent, and you could define first class language constructs 
inline, no sweat.  It really freed the mind to think about the problem, 
instead of the language and its idiosyncracies.


DaveA

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-19 Thread Johan Grönqvist

Sean DiZazzo skrev:

I would do something like this:


class Namespace(object):

... pass
...

n = Namespace()
n.f = 2
n.g = 4
print f

Traceback (most recent call last):
  File "", line 1, in ?
NameError: name 'f' is not defined

print n.f

2


I like this solution. This also minimizes the extra code if I would want 
to explicitly delete the bindings, as I would only need one line to 
delete the Namespace object.


Thanks!

Johan

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-19 Thread Johan Grönqvist

Gabriel Genellina skrev:
En Fri, 18 Sep 2009 10:55:47 -0300, Johan Grönqvist 
 escribió:


Summarizing the answers, it seems that I will try to follow three 
suggestions:


3) If I define a few values intended to be used very locally, delete 
those after use.


Why bother? Unless they're big objects and you want to ensure they get 
deleted as soon as possible.


To ease debugging.

Perhaps the problem only appears because I use longer functions than 
recommended for python, but I have functions containing 2 to 4 loops, 
with several if-clause each, where the different parts use very similar 
variable names, like x, y, z, dr, dr_2, dr_3 etc.


None of the code fragments uses all of the names, but every fragment 
uses some of them. I have had typos that incorrectly reused values from 
a previous fragment. In those cases, it would have been much easier to 
debug a raised exception due to using an undefined name, than to debug a 
slightly incorrect result due to some if-clause of some loop computing 
with an incorrect value.



Regards


Johan

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-18 Thread Sean DiZazzo
On Sep 11, 10:36 am, Johan Grönqvist 
wrote:
> Hi All,
>
> I find several places in my code where I would like to have a variable
> scope that is smaller than the enclosing function/class/module definition.
>
> One representative example would look like:
>
> --
> spam = { ... }
> eggs = { ... }
>
> ham = (a[eggs], b[spam])
> --
>
> The essence is that for readability, I want spam and eggs in separate
> definitions, but for clarity, I would like to express the fact that they
> are "local to the definition of ham", i.e., they are not used outside of
>   the definition of ham.
>
> The language reference at
>  says that "The
> following are blocks: a module, a function body, and a class
> definition." (all other cases seem to refer to dynamic execution using
> eval() or similar). Python 3 and 2.6 seem to have identical scope rules.
>
> In the other languages I have used I can either use braces (C and
> descendants) or use let-bindings (SML, Haskell etc.) to form local scopes.
>
> Are there suggestions or conventions to maximize readability for these
> cases in python? (Execution time is not important in the cases I
> currently consider.)
>
> Regards
>
> Johan

I would do something like this:

>>> class Namespace(object):
... pass
...
>>> n = Namespace()
>>> n.f = 2
>>> n.g = 4
>>> print f
Traceback (most recent call last):
  File "", line 1, in ?
NameError: name 'f' is not defined
>>> print n.f
2

~Sean
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-18 Thread Gabriel Genellina
En Fri, 18 Sep 2009 10:55:47 -0300, Johan Grönqvist  
 escribió:


Summarizing the answers, it seems that I will try to follow three  
suggestions:


1) In general, try to restructure the code into smaller modules and  
smaller functions.


That's a good thing - "manageable" modules and functions.

2) When using many local variables bindings to create one larger object,  
define an inner function that hides those bindings.


I'd say, not to *hide* those bindings, but because the code fragment  
deserves logically to become a function.


3) If I define a few values intended to be used very locally, delete  
those after use.


Why bother? Unless they're big objects and you want to ensure they get  
deleted as soon as possible.


--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-18 Thread Johan Grönqvist

Thanks for all replies.

First, two general comments, and then my conclusions:

I did not intend to ask for new features, but my interest was in writing 
readable code that works in python 2.5, although I may upgrade to 2.6 soon.


Also, what I gave was intended as a minimal example, and not a complete 
use case.



Summarizing the answers, it seems that I will try to follow three 
suggestions:


1) In general, try to restructure the code into smaller modules and 
smaller functions.


2) When using many local variables bindings to create one larger object, 
define an inner function that hides those bindings.


3) If I define a few values intended to be used very locally, delete 
those after use.


Thanks again,

Johan

--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-18 Thread Wolfgang Rohdewald
On Friday 18 September 2009, Ethan Furman wrote:
> loop != scope

true for python but in some languages the loop
counter has a scope limited to the loop


-- 
Wolfgang
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-18 Thread Ethan Furman

Neal Becker wrote:

markol...@gmail.com wrote:



On Sep 11, 7:36 pm, Johan Grönqvist  wrote:


Hi All,

I find several places in my code where I would like to have a variable
scope that is smaller than the enclosing function/class/module
definition.


This is one of the single major frustrations I have with Python and a
important source of bugs for me. Here is a typical situation

for i, j in visited:
   a[i, j] = 1
for i in range(rows):
   a[i, 0] = 1
for j in range(columns):
   a[0, i] = 1

As you see the third loop has a bug (I am actually mixing two logics:
1) using i for rows and j for columns 2) using i for the first
iterator and j for the second). The result is a buggy code that is
tolerated by Python. In C++ or Perl I don't have this problem. I
wonder whether other people share this opinion and if we have ever had
PEPs trying to address that...

Marko



I agree.  I wish there were a convenient way to switch this 'feature' 
on/off.  I believe the vast majority of the time I do not want variable 
names leaking out into other scopes.  OTOH, sometimes it's convenient.




loop != scope

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-18 Thread Neal Becker
markol...@gmail.com wrote:

> On Sep 11, 7:36 pm, Johan Grönqvist  wrote:
>> Hi All,
>>
>> I find several places in my code where I would like to have a variable
>> scope that is smaller than the enclosing function/class/module
>> definition.
> 
> This is one of the single major frustrations I have with Python and a
> important source of bugs for me. Here is a typical situation
> 
> for i, j in visited:
> a[i, j] = 1
> for i in range(rows):
> a[i, 0] = 1
> for j in range(columns):
> a[0, i] = 1
> 
> As you see the third loop has a bug (I am actually mixing two logics:
> 1) using i for rows and j for columns 2) using i for the first
> iterator and j for the second). The result is a buggy code that is
> tolerated by Python. In C++ or Perl I don't have this problem. I
> wonder whether other people share this opinion and if we have ever had
> PEPs trying to address that...
> 
> Marko

I agree.  I wish there were a convenient way to switch this 'feature' 
on/off.  I believe the vast majority of the time I do not want variable 
names leaking out into other scopes.  OTOH, sometimes it's convenient.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-18 Thread markol...@gmail.com
On Sep 11, 7:36 pm, Johan Grönqvist  wrote:
> Hi All,
>
> I find several places in my code where I would like to have a variable
> scope that is smaller than the enclosing function/class/module definition.

This is one of the single major frustrations I have with Python and a
important source of bugs for me. Here is a typical situation

for i, j in visited:
a[i, j] = 1
for i in range(rows):
a[i, 0] = 1
for j in range(columns):
a[0, i] = 1

As you see the third loop has a bug (I am actually mixing two logics:
1) using i for rows and j for columns 2) using i for the first
iterator and j for the second). The result is a buggy code that is
tolerated by Python. In C++ or Perl I don't have this problem. I
wonder whether other people share this opinion and if we have ever had
PEPs trying to address that...

Marko
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-12 Thread Daniel Stutzbach
On Sat, Sep 12, 2009 at 10:02 AM, Ethan Furman  wrote:

> That's probably why he called it as:
> with do_nothing() as *imaginary*_local_scope:
>...
>del spam, eggs, imaginary_local_scope
>
> and then as the last item deleted all the variables, except the one he
> wanted to keep.
>

You're absolutely right.  My apologies.  I need to learn not to post to
mailing lists first thing in the morning! ;-)

--
Daniel Stutzbach, Ph.D.
President, Stutzbach Enterprises, LLC 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-12 Thread Ethan Furman

Daniel Stutzbach wrote:
On Fri, Sep 11, 2009 at 8:29 PM, Steven D'Aprano 
> wrote:


(4) Create a "do nothing" context manager allowing you to visually
indent
the block, but otherwise have no effect:


"with" doesn't create a new scope.


That's probably why he called it as:

with do_nothing() as *imaginary*_local_scope:
...
del spam, eggs, imaginary_local_scope

and then as the last item deleted all the variables, except the one he 
wanted to keep.


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-12 Thread Daniel Stutzbach
On Fri, Sep 11, 2009 at 8:29 PM, Steven D'Aprano <
st...@remove-this-cybersource.com.au> wrote:

> (4) Create a "do nothing" context manager allowing you to visually indent
> the block, but otherwise have no effect:
>

"with" doesn't create a new scope.  Observe:

Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> with open('/dev/null') as f:
...   x = 5
...
>>> x
5

--
Daniel Stutzbach, Ph.D.
President, Stutzbach Enterprises, LLC 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-12 Thread Jorgen Grahn
On Fri, 11 Sep 2009 19:07:55 -0700 (PDT), Bearophile  
wrote:
...
> No need to add other things to the
> language as the OP suggests.

He didn't suggest that (although he did give examples from other
languages).

Personally ... yes, I sometimes feel like the OP, but usually if I
want that kind of subtle improvements, I am also willing to
restructure my code so the natural scopes become short enough.

/Jorgen

-- 
  // Jorgen GrahnO  o   .
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Bearophile
Steven D'Aprano:

> (3) Create an inner function, then call that.

Several people after someone gives this anwer.


> My personal opinion is that if you really need a local scope inside a 
> function, the function is doing too much and should be split up.<

I agree. And a way to split a function is to define an inner function,
that's one of their main purposes. No need to add other things to the
language as the OP suggests.

Bye,
bearophile
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Steven D'Aprano
On Fri, 11 Sep 2009 19:36:14 +0200, Johan Grönqvist wrote:

> Hi All,
> 
> I find several places in my code where I would like to have a variable
> scope that is smaller than the enclosing function/class/module
> definition.
...
> The essence is that for readability, I want spam and eggs in separate
> definitions, but for clarity, I would like to express the fact that they
> are "local to the definition of ham", i.e., they are not used outside of
>   the definition of ham.

Personally, I don't think your use-case is the least bit convincing, and 
I think that introducing a new scope would hurt readability and clarity 
rather than help it, but if you really want this, there are a couple of 
approaches:

(1) Use comments to give your intention.

spam = 'abc'  # Used only in definition of ham.
eggs = 'def'  # Likewise.
ham = (a[eggs], b[spam])


(2) Delete the local names afterwards.

spam = 'abc'
eggs = 'def'
ham = (a[eggs], b[spam])
del spam, eggs


(3) Create an inner function, then call that.

def outer(*args):
a = parrot()
b = spanish_inquistion()
def inner():
spam = 'abc'
eggs = 'def'
return a[eggs], b[spam]
ham = inner()
return do_something_with(ham)


(4) Create a "do nothing" context manager allowing you to visually indent 
the block, but otherwise have no effect:

class do_nothing:
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
pass

ham = ()
with do_nothing() as imaginary_local_scope:
spam = 'abc'
eggs = 'def'
ham = a[eggs], b[spam]
del spam, eggs, imaginary_local_scope


I think the fourth is an abomination and I only mention it for completion.

My personal opinion is that if you really need a local scope inside a 
function, the function is doing too much and should be split up.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Carl Banks
On Sep 11, 10:36 am, Johan Grönqvist 
wrote:
> In the other languages I have used I can either use braces (C and
> descendants) or use let-bindings (SML, Haskell etc.) to form local scopes.

I wouldn't mind a let statement but I don't think the language really
suffers for the lack of it.  I expect that "leaky scopes" are a really
minor source of bugs in practice**, especially with well-organized
code that results in small functions.  The main loss is the
organization opportunity.

Having said that, I'll tell you a pretty spiffy way to do it, even
though it can't be regarded as anything other than a cute hack.  I
don't recommend using it in practice.


First define a decorator:

def let(f): return f()


Then, apply this decorator to a nameless function to get a convenient
nested scope:

@let
def _():
a = 1
b = 2
print a,b


But there's more: you can define let bindings in the function
arguments:

@let
def _(a = 1, b = 2):
print a,b


And, as with LISP, the "let" "statement" can return a result which you
can bind to a local variable:

@let
def result(a = 1, b = 2):
return a + b

print result


Don't do this in real code, though.  Just live with the limitation, or
define a nested function and call it explicitly without cute decorator
hacks.


Carl Banks


(**) There is one notable common bug that leaky scopes do cause, when
creating closures in a loop.  However, that is an advanced usage.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Terry Reedy

Johan Grönqvist wrote:

Hi All,

I find several places in my code where I would like to have a variable
scope that is smaller than the enclosing function/class/module definition.

One representative example would look like:

--
spam = { ... }
eggs = { ... }

ham = (a[eggs], b[spam])
--

The essence is that for readability, I want spam and eggs in separate
definitions, but for clarity, I would like to express the fact that they
are "local to the definition of ham", i.e., they are not used outside of
 the definition of ham.


delete spam, eggs

rather effectively says that the reader can also forget the bindings.
Execution time is minimal since no object is gc'ed.

This works with function locals also:

>>> def f():
i=1; del i; print (i)


>>> f()
Traceback (most recent call last):
  File "", line 1, in 
f()
  File "", line 2, in f
i=1; del i; print (i)
UnboundLocalError: local variable 'i' referenced before assignment

However, since probably a majority of non-function bindings are rather 
local, I do not see that this really improved readability.


Within a module intended to be imported, using _spam, _eggs would signal 
that they are only inted for local use. Delete if you want to enforce that.



The language reference at
 says that "The
following are blocks: a module, a function body, and a class
definition." (all other cases seem to refer to dynamic execution using
eval() or similar). Python 3 and 2.6 seem to have identical scope rules.


Not exactly. In 3.0, comprehensions define a new scope by virtue of 
being implicit function bodies.



In the other languages I have used I can either use braces (C and
descendants) or use let-bindings (SML, Haskell etc.) to form local scopes.


I consider that simplicity of Python scoping to be a major feature; it 
is one of the reasons I use it.


tjr


--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Ethan Furman

Patrick Sabin wrote:

Johan Grönqvist schrieb:


Hi All,

I find several places in my code where I would like to have a variable
scope that is smaller than the enclosing function/class/module 
definition.


One representative example would look like:

--
spam = { ... }
eggs = { ... }

ham = (a[eggs], b[spam])
--


[snip]

1) If you define all this in the global namespace you could remove your 
temporary variables afterwards, e.g.


spam = 1
ham = (spam,)
del globals()['spam']


Why use globals()?  You could just say

del spam

and be done with it.

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Daniel Stutzbach
2009/9/11 Johan Grönqvist 

> I find several places in my code where I would like to have a variable
> scope that is smaller than the enclosing function/class/module definition.
>

For what it's worth, there was a relevant proposal on the python-ideas list
a few months back:

http://mail.python.org/pipermail/python-ideas/2009-July/005114.html


--
Daniel Stutzbach, Ph.D.
President, Stutzbach Enterprises, LLC 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Patrick Sabin

Johan Grönqvist schrieb:

Hi All,

I find several places in my code where I would like to have a variable
scope that is smaller than the enclosing function/class/module definition.

One representative example would look like:

--
spam = { ... }
eggs = { ... }

ham = (a[eggs], b[spam])
--

The essence is that for readability, I want spam and eggs in separate
definitions, but for clarity, I would like to express the fact that they
are "local to the definition of ham", i.e., they are not used outside of
 the definition of ham.

The language reference at
 says that "The
following are blocks: a module, a function body, and a class
definition." (all other cases seem to refer to dynamic execution using
eval() or similar). Python 3 and 2.6 seem to have identical scope rules.

In the other languages I have used I can either use braces (C and
descendants) or use let-bindings (SML, Haskell etc.) to form local scopes.

Are there suggestions or conventions to maximize readability for these
cases in python? (Execution time is not important in the cases I
currently consider.)


Regards

Johan


I think it is not possible to realize something like braces in C or 
let-bindings in python. But here are some Ideas to work around this problem:


1) If you define all this in the global namespace you could remove your 
temporary variables afterwards, e.g.


spam = 1
ham = (spam,)
del globals()['spam']

This only works for the global namespace and not for the local! I 
wouldn't recommend it.


2) create a method, which initializes ham

def make_ham():
spam = {...}
egg = {...}
return (egg, spam)

ham = make_ham()

This makes it easier to reuse ham in other situations and wouldn't 
expose spam or egg.


3) Make a class for your ham data structure

If ham is so complex that you have to split it up, it may makes sense to 
create a class for it. Of course this would need refactoring of the 
code, but it's more readable and extensible than packing your data in 
tuples, lists or dictionaries.


- Patrick
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-09-11 Thread Neal Becker
Johan Grönqvist wrote:

> Hi All,
> 
> I find several places in my code where I would like to have a variable
> scope that is smaller than the enclosing function/class/module definition.
> 
> One representative example would look like:
> 
> --
> spam = { ... }
> eggs = { ... }
> 
> ham = (a[eggs], b[spam])
> --
> 
> The essence is that for readability, I want spam and eggs in separate
> definitions, but for clarity, I would like to express the fact that they
> are "local to the definition of ham", i.e., they are not used outside of
>   the definition of ham.
> 
> The language reference at
>  says that "The
> following are blocks: a module, a function body, and a class
> definition." (all other cases seem to refer to dynamic execution using
> eval() or similar). Python 3 and 2.6 seem to have identical scope rules.
> 
> In the other languages I have used I can either use braces (C and
> descendants) or use let-bindings (SML, Haskell etc.) to form local scopes.
> 
> Are there suggestions or conventions to maximize readability for these
> cases in python? (Execution time is not important in the cases I
> currently consider.)
> 
I'd like this also.

-- 
http://mail.python.org/mailman/listinfo/python-list