2 questions about scope

G

Gabriel Zachmann

I am relatively new to python, but i know some other languages, such as C++,
fairly well.
After reading up a little bit in the reference manual, section 4.1,
and searching this NG, i still have 2 questions about python's scoping
rules.

1. Exactly what are the major differences between python's and C++ scoping
rules?

2. Why is it that 'while', 'for', etc., don't introduce a new block?
(so that variables bound inside those blocks would be local to those
blocks only?)

I will be most grateful for all insights or pointers to literature.

Best regards,
Gabriel.

--
/-------------------------------------------------------------------------\
| We act as though comfort and luxury |
| were the chief requirements of life, |
| when all that we need to make us happy |
| is something to be enthusiastic about. (Einstein) |
+-------------------------------------------------------------------------+
| (e-mail address removed)-bonn.de __@/' www.gabrielzachmann.org |
\-------------------------------------------------------------------------/
 
J

Josiah Carlson

Gabriel Zachmann said:
I am relatively new to python, but i know some other languages, such as C++,
fairly well.
After reading up a little bit in the reference manual, section 4.1,
and searching this NG, i still have 2 questions about python's scoping
rules.

1. Exactly what are the major differences between python's and C++ scoping
rules?

Most of the differences you will never run into. Here are two that may
effect you in time.
... b = 2
... def g():
... c = 3
... def h():
... d = 4
... print a,b,c,d
... h()
... g()
...1 2 3 4
... b = 2
... def g():
... global a,b
... a = 2
... b = 3
... g()
... print a, b
...3

Generally, you always have read-only access to parent-level scopes, but
if you want write-access to non-global parent scopes, you are out of
luck unless you use object attributes.
... pass
...... data = a()
... data.sub = 1
... def g():
... data.sub = 2
... g()
... print data.sub
...
2


2. Why is it that 'while', 'for', etc., don't introduce a new block?
(so that variables bound inside those blocks would be local to those
blocks only?)

Last time I checked, C++ didn't introduce new scopes for for and while
loops. I would imagine Python doesn't introduce new scopes for three
reasons: it is easier not to, not doing so simplifies some algorithms
(name munging can address the "but I wanted that variable" complaints)
and "Flat is better than nested".

- Josiah
 
A

Andrew Dalke

Neal said:
Actually, these don't introduce a block in c++ either. The braces do.

In C++

for (int i=0; i<100; spam(i), ++i)
;

the 'i' is in the for statement's scope even though there
are no braces.

To respond to the OP's question, one big difference between
C++ and Python's scoping systems is that Python doesn't have
a distinct variable declaration. In C++ you could say

{
char i[] = "something";
...
for (int i=0; i<100; i++) {
...
}
}

and the compiler knows you want a new variable 'i'.

In Python, the equivalent might be

i = "something"
for i in range(100):
...

There's nothing to tell Python that the 'i' used
in the for statement is different than the i in the
outer scope, so it assumes you meant the same variable.

The only scopes created in Python are for modules,
classes, and functions. As I pointed out a couple
weeks ago, you could fake scope with a class statement,
as in

i = "something"
class scope:
for i in range(100):
...

but you really shouldn't. Or use a function scope,

i = "something"
def scope():
for i in range(100):
...
scope()

I mostly use the last when I want some non-trivial
initialization in my module and don't want the various
variables hanging around in the process space. I'll
also follow it up with a "del scope" so that no one
can reference the initialization code.


Andrew
(e-mail address removed)
 
A

Alex Martelli

Andrew Dalke said:
but you really shouldn't. Or use a function scope,

i = "something"
def scope():
for i in range(100):
...
scope()

I mostly use the last when I want some non-trivial
initialization in my module and don't want the various
variables hanging around in the process space. I'll
also follow it up with a "del scope" so that no one
can reference the initialization code.

Execution in function scope is also generally quite a bit faster than
execution at module scope or in class scope. Any nontrivial code in
module scope is best scooped up into a function, which is then executed
and removed. I'd suggest naming the function '_init' or something like
that -- with a leading underscore to indicate to the reader of the
source that it's a private implementation detail (not _needed_, since
you're gonna delete it after running it once, but helpful to the reader
at no cost to the code's author).


Alex
 

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,769
Messages
2,569,582
Members
45,058
Latest member
QQXCharlot

Latest Threads

Top