Re: [Tutor] how to make an lexical scope block?

2017-08-06 Thread Alan Gauld via Tutor
CCing the list.
Always use ReplyAll or ReplyList when responding to the list.

On 05/08/17 18:17, Xiaosong Chen wrote:
> 2) Also we avoid importing with the
>> from foo import *
>>
>> even if you import with
>>
>> import foo
>>
>> foo.temp can still be accessed. When you use autocomplete in an
>> interactive shell like ipython, it might become an item.

foo.temp does not pose a problem of name pollution because you have
to prefix it with foo. Thus every module can have a temp variable and
there is no risk of names clashing because they all need to be
accessed with name.temp. You can even compare them:

if foo.temp < bar.temp

> 3) We need fewer temporary variables because we can use
>> tuple unpacking and generator expressions to replace many
>> scenarios where C would use a temporary variable.
> I know little with python's xxx comprehension. In my memory, temporary
> variables seem not allowed inside, and the same for lambda
> expressions. Might you give some examples?
>
Things like list comprehensions often replace explicit loops which
would introduce extra named variables. Consider:

>>> lst = [n for n in range(7)]
>>> n
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'n' is not defined
>>> lst
[0, 1, 2, 3, 4, 5, 6]
>>> lst2 = []
>>> for n in range(7): lst2.append(n)
...
>>> n
6
>>> lst2
[0, 1, 2, 3, 4, 5, 6]
>>>

You can see how in the list comprehension case n
is not visible outside the comprehension whereas n
exists outside the for loop(as you noted in your original
post) so, by using the comprehension we reduce
the number of visible names.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to make an lexical scope block?

2017-08-05 Thread Alan Gauld via Tutor
On 05/08/17 08:23, Xiaosong Chen wrote:
> In C, it's a common pattern to use temporary variables in an lexical
> scope to prevent the global scope from getting dirty.

This was very common in the early days of C - around 1979-1985 - when
compilers often only considered the first 4 (or 6) characters of a
variable name - even though the name itself could be 16 or 32
characters long.

Thus 'index' and 'indeterminate' and 'indent' were all seen
as the same name. This required careful limiting of the lexical
scope of variables. Nowadays I don't see that as an issue and
most of the C code I work with doesn't limit scope beyond
a function definition. Maybe some old school C programmers
still worry about tight scoping but not the ones I work with!

As for Python it limits names to global (actually module)
and function scope. If you are creating well structured
code based on short clear functions there should not be
much of a problem.

So, to answer the question,

1) we don't tend to need such scoping because the language
permits many names, and it provides module and function scopes.

2) Also we avoid importing with the

from foo import *

style which increases risks of name pollution.

3) We need fewer temporary variables because we can use
tuple unpacking and generator expressions to replace many
scenarios where C would use a temporary variable.

In practice I've never found it to be an issue.

HTH

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to make an lexical scope block?

2017-08-05 Thread Steven D'Aprano
On Sat, Aug 05, 2017 at 03:23:57PM +0800, Xiaosong Chen wrote:
> In C, it's a common pattern to use temporary variables in an lexical
> scope to prevent the global scope from getting dirty.
[...]
> But in python, such a pattern seems impossible. An straightforward
> translation should be like this:
> 
> ```python
> a = []
> for i in range(N):
> temp = ...
> a.append(...)# something got from temp
> # temp DO EXISTS here, will be the value of the last iteration
> ```
> 
> As in the comment, the temporary variable remains existing after the
> block. How do you usually deal with this?


If you use functions (or methods), as you should, then temp will be a 
local variable of the function, and it doesn't matter if it still exists 
after the for loop. It is hidden inside the function scope, and cannot 
affect the global scope.

If you are using global scope, as sometimes is needed, then it depends. 
If this is a script that you run, then it really doesn't matter. A few 
temporary variables more or less doesn't make the script any better or 
worse. Don't worry about it.

If it is a library, where a nice clean global namespace is important, 
you can either refactor the code to make the problem go away, or delete 
the name when you are done:

del temp

deletes the name "temp" from the current namespace.

-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to make an lexical scope block?

2017-08-05 Thread Peter Otten
Xiaosong Chen wrote:

> In C, it's a common pattern to use temporary variables in an lexical
> scope to prevent the global scope from getting dirty.
> For example,
> 
> ```C
> int a[N];
> for (int i = 0; i < N; i++) {
>   int temp = ...
>   a[i] = ... // something got from temp
> }
> // temp do not exists here
> ```
> 
> But in python, such a pattern seems impossible. An straightforward
> translation should be like this:
> 
> ```python
> a = []
> for i in range(N):
> temp = ...
> a.append(...)# something got from temp
> # temp DO EXISTS here, will be the value of the last iteration
> ```
> 
> As in the comment, the temporary variable remains existing after the
> block. How do you usually deal with this?

I put the code into a function

def create_a(n):
result = []
for i in range(n):
temp = ...
result.append(...)
return result

a = create_a(N)

At this point you could delete the function

del create_a

but in practice I never do that. 

If you want to go fancy you can rewrite the above as

def replace_with_result(*args, **kw):
def call(f):
return f(*args, **kw)
return call

@replace_with_result(N)
def a(n):
result = []
for i in range(n):
temp = ...
result.append(...)
return result

which will immediately overwrite the function a() with the result of the 
a(N) call -- but I prefer to keep the function around. 

The extra memory is usually negligible, and writing unit tests to detect 
blunders in create_a() is always a good idea, as trivial as it might appear 
on first sight...

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] how to make an lexical scope block?

2017-08-05 Thread Xiaosong Chen
In C, it's a common pattern to use temporary variables in an lexical
scope to prevent the global scope from getting dirty.
For example,

```C
int a[N];
for (int i = 0; i < N; i++) {
  int temp = ...
  a[i] = ... // something got from temp
}
// temp do not exists here
```

But in python, such a pattern seems impossible. An straightforward
translation should be like this:

```python
a = []
for i in range(N):
temp = ...
a.append(...)# something got from temp
# temp DO EXISTS here, will be the value of the last iteration
```

As in the comment, the temporary variable remains existing after the
block. How do you usually deal with this?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor