Is an interactive command a block?

A

Alf P. Steinbach

The CPython 3.1.1 language reference §4.1 says

"Each command typed interactively is a block."

It also says

"If a name is bound in a block, it is a local variable of that block, unless
declared as nonlocal"

Even with a non-literal try-for-best-meaning reading I can't get this to mesh
with the actual behavior of the interpreter, e.g.
... fandango = 666
...
My current understanding is (A) that the interpreter is correct in this respect
(for one would harldly want the effects of statements to be fundamentally
different in interpreted mode, except the presentation of expression results),
and (B), but here I'm less sure, that the documentation is incorrect.

So what I'm asking about is mainly (B), because if the documentation is correct
after all, then there's something I haven't grokked. :)


Cheers,

- Alf
 
S

Steven D'Aprano

The CPython 3.1.1 language reference §4.1 says

"Each command typed interactively is a block."

It also says

"If a name is bound in a block, it is a local variable of that block,
unless
declared as nonlocal"

Even with a non-literal try-for-best-meaning reading I can't get this to
mesh with the actual behavior of the interpreter, e.g.

... fandango = 666
...

My current understanding is (A) that the interpreter is correct in this
respect (for one would harldly want the effects of statements to be
fundamentally different in interpreted mode, except the presentation of
expression results), and (B), but here I'm less sure, that the
documentation is incorrect.


Why do you say that? I don't see what it is in the command you typed that
leads you to think the documentation is incorrect.

The first command you type is:

for x in "poi":
fandango = 666


which binds two names, x and fandango. Since you are not typing them in a
function or class definition, locals() is globals() and the two local
names you create happen to also be globals.

The next two commands you type:

fandango
_

don't bind anything, so aren't relevant.

If it helps:

.... fandango = 666
....
locals() is globals() True
fandango 666
locals()['fandango'] 666
import __main__
__main__.fandango
666
 
A

Alf P. Steinbach

* Steven D'Aprano:
Why do you say that? I don't see what it is in the command you typed that
leads you to think the documentation is incorrect.

The first command you type is:

for x in "poi":
fandango = 666


which binds two names, x and fandango. Since you are not typing them in a
function or class definition, locals() is globals() and the two local
names you create happen to also be globals.

Thanks, that may be it.

In most other languages I'm familiar with, if a name is local then it isn't
global (and vice versa), and I had that as an underlying assumption since it
doesn't appear to be mentioned in the documentation.

However, I find a language reference statement that alludes to this: "(The
variables of the module code block are local and global.)"

Hm...

The next two commands you type:

fandango
_

don't bind anything, so aren't relevant.

Well it showed that 'fandango' had been defined as a global. :)

If it helps:

... fandango = 666
...
locals() is globals() True
fandango 666
locals()['fandango'] 666
import __main__
__main__.fandango
666

Yeah, helps.

I feel that there's still something lacking in my understanding though, like
how/where the "really actually just pure local not also global" is defined for
function definition, but it's now just a vague feeling of something missing, not
a feeling of direct contradiction as I had when I believed local != global.


Cheers, & thanks,

- Alf
 
B

Benjamin Kaplan

* Steven D'Aprano:
Why do you say that? I don't see what it is in the command you typed that
leads you to think the documentation is incorrect.

The first command you type is:

for x in "poi":
   fandango = 666


which binds two names, x and fandango. Since you are not typing them in a
function or class definition, locals() is globals() and the two local names
you create happen to also be globals.

Thanks, that may be it.

In most other languages I'm familiar with, if a name is local then it isn't
global (and vice versa), and I had that as an underlying assumption since it
doesn't appear to be mentioned in the documentation.

However, I find a language reference statement that alludes to this: "(The
variables of the module code block are local and global.)"

Hm...

The next two commands you type:

fandango
_

don't bind anything, so aren't relevant.

Well it showed that 'fandango' had been defined as a global. :)

If it helps:

for x in "poi":

...     fandango = 666
...
locals() is globals()
True

666
locals()['fandango']

666

import __main__
__main__.fandango

666

Yeah, helps.

I feel that there's still something lacking in my understanding though, like
how/where the "really actually just pure local not also global" is defined
for function definition, but it's now just a vague feeling of something
missing, not a feeling of direct contradiction as I had when I believed
local != global.

It's because the only blocks in python that have their own scope are
classes and functions. For loops don't have their own scope- they use
the enclosing one, which in this case is globals.
 
A

Alf P. Steinbach

* Benjamin Kaplan:
It's because the only blocks in python that have their own scope are
classes and functions. For loops don't have their own scope- they use
the enclosing one, which in this case is globals.

Thanks, but hey, contradiction: you mention globals as an "enclosing" scope,
i.e. that a module can have a scope, while stating that only classes and
functions have their own scope (so, would a module have it's not own scope?).

I think, having now read up and down and sideways in the docs, that the proper
term in Python is "namespace", and that "scope" in Python refers to where the
names in a namespace are directly accessible, with a special case for classes,
namely that the scope of a class' namespace doesn't penetrate down into function
definitions, hence problem with comprehensions expressed directly in a class
definition. I believe that's a so called language "wart" -- which C++ is full
of, just now discovering some of Python's :). It's almost like C++'s "most
vexing parse", a natural and apparently meaningful source code construct that
due to the detailed rules turns out to be meaningless. I wish language designers
could be a little less hooked on low level consistency. Because it makes for
high level inconsistency, very difficult to explain without zillions of details.

But anyways, it's starting to make more sense, yes.


Cheers,

- Alf
 
E

Ethan Furman

Alf said:
* Benjamin Kaplan:


Thanks, but hey, contradiction: you mention globals as an "enclosing"
scope, i.e. that a module can have a scope, while stating that only
classes and functions have their own scope (so, would a module have it's
not own scope?).

module scope == global scope

That is, there is nothing higher than module scope. (So, yes, global is
a slight misnomer... in Python it means 'global to a module'.)

~Ethan~
 
S

Steven D'Aprano

module scope == global scope

That is, there is nothing higher than module scope. (So, yes, global is
a slight misnomer... in Python it means 'global to a module'.)

Actually there is: built-ins.

That's why you can access (e.g.) len without having to define it, or
import it, first. And what's more, you can do this:

len([1,2,3]) 3
def len(x): # Shadow the built-in
.... return -3
....
len([1,2,3]) -3
del len
len([1,2,3]) # It's back!
3
 
E

Ethan Furman

Steven said:
module scope == global scope

That is, there is nothing higher than module scope. (So, yes, global is
a slight misnomer... in Python it means 'global to a module'.)

Actually there is: built-ins.

That's why you can access (e.g.) len without having to define it, or
import it, first. And what's more, you can do this:
len([1,2,3])
3
def len(x): # Shadow the built-in
... return -3
...
len([1,2,3])
-3
del len
len([1,2,3]) # It's back!

3

Very good point, I had forgotten. Of course, injecting into built-ins
is not recommended.

~Ethan~
 

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

Staff online

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top