Exception handling with NameError

Z

Zeynel

Hello,

I want to append new input to list SESSION_U without erasing its
content. I try this:

....
try:
SESSION_U.append(UNIQUES)
except NameError:
SESSION_U = []
SESSION_U.append(UNIQUES)
....
I would think that at first try I would get the NameError and
SESSION_U list would be created and appended; the second time try
would work. But it does not. Do you know why?
 
P

Peter Otten

Zeynel said:
I want to append new input to list SESSION_U without erasing its
content. I try this:

...
try:
SESSION_U.append(UNIQUES)
except NameError:
SESSION_U = []
SESSION_U.append(UNIQUES)
...
I would think that at first try I would get the NameError and
SESSION_U list would be created and appended; the second time try
would work. But it does not. Do you know why?

If you want SESSION_U to be global you must say so. E. g.:

def your_func():
global SESSION_U
# ...
try:
SESSION_U.append(UNIQUES)
except NameError:
SESSION_U = []
SESSION_U.append(UNIQUES)
# ...

Of course I'm only guessing because you don't provide enough context.

Peter
 
D

Dennis Lee Bieber

Hello,

I want to append new input to list SESSION_U without erasing its
content. I try this:

...
try:
SESSION_U.append(UNIQUES)
except NameError:
SESSION_U = []
SESSION_U.append(UNIQUES)
...
I would think that at first try I would get the NameError and
SESSION_U list would be created and appended; the second time try
would work. But it does not. Do you know why?

The concept works here...

-=-=-=-=-.... session.append("something")
.... except NameError:
.... session = ["else"]
....
-=-=-=-=-

Note that you don't need to "create" an empty list and then append
the first item into it, just wrap the item in the [] pair.

Second -- style-wise, names in all caps are normally considered to
represent CONSTANT values

TWO_PI = 3.14159265436 * 2.0

not items that are going to change each time through...


I'd suspect something else is wrong. Is your try/except buried
inside some function, and are you expecting "session_u" to be a global?
If so, you'd probably have to declare it as a global in the function to
get this to work -- more likely you are getting an unbound local
exception (without a global declaration binding [] to the name in the
except side is forcing the name to be a local variable, so trying to
reference it may create a different error... but... No, still works here

-=-=-=-=-.... try:
.... session.append("something")
.... except NameError:
.... session = ["else"]
.... return session
....
test() ['else']
test() ['else']
test() ['else']
-=-=-=-=-

Of course, being a local inside the function means multiple calls
will just create a fresh local.
 
Z

Zeynel

Of course I'm only guessing because you don't provide enough context.

Peter

Thanks.

This is the problem I am having, in general:

K = [] # a container list
K = ["A", "B"]

ARCHIVE = [] # a list where items from K is archived

ARCHIVE.append(K)

# K is updated
K = ["C", "D"]

# append new K to ARCHIVE
ARCHIVE.append(K)

The problem I am having is this: If I do:

K = []
ARCHIVE = []
ARCHIVE.append(K)

any time K is updated (user submits new input) the content of ARCHIVE
is erased:

If I do this:

K = []
ARCHIVE.append(K)

I get NameError: "Name ARCHIVE not defined"

What is the solution?
 
D

Dennis Lee Bieber

This is the problem I am having, in general:

K = [] # a container list
K = ["A", "B"]

ARCHIVE = [] # a list where items from K is archived

ARCHIVE.append(K)

# K is updated
K = ["C", "D"]

# append new K to ARCHIVE
ARCHIVE.append(K)

The problem I am having is this: If I do:

K = []
ARCHIVE = []
ARCHIVE.append(K)

any time K is updated (user submits new input) the content of ARCHIVE
is erased:
No, it is NOT erased... It is MUTATED...

Study the Python documentation on mutable objects AND on Python's
object binding semantics.

For the latter, the clue is that NAMES are bound to objects, rather
than objects being stored "in" names.

k = []

binds (attaches) the name "k" to a mutable object (an empty list).

archive.append(k)

binds the next "slot" in the list "archive" to the OBJECT that is
currently bound to "k". So (if archive had been empty) BOTH
k
and
archive[0]
are bound to the SAME OBJECT.

If, somewhere in the code, you do a mutating operation on "k" (say,
k.append(xxx)), then both "k" and "archive[0]" will reflect the result
of the operation, as they both are "names" for the same object.

So... you either have to force the append to use a copy of "k"
(presuming a shallow structure)

archive.append(k[:])

or you break the binding of the name "k" after doing the append

archive.append(k)
k = [] #binds the name "k" to a NEW empty list

If I do this:

K = []
ARCHIVE.append(K)

I get NameError: "Name ARCHIVE not defined"

What is the solution?
 
P

Peter Otten

Dennis said:
The problem I am having is this: If I do:

K = []
ARCHIVE = []
ARCHIVE.append(K)

any time K is updated (user submits new input) the content of ARCHIVE
is erased:
No, it is NOT erased... It is MUTATED...

But he rebinds the ARCHIVE name.
 
P

Peter Otten

Zeynel said:
Of course I'm only guessing because you don't provide enough context.

Peter

Thanks.

This is the problem I am having, in general:

K = [] # a container list
K = ["A", "B"]

ARCHIVE = [] # a list where items from K is archived

ARCHIVE.append(K)

# K is updated
K = ["C", "D"]

# append new K to ARCHIVE
ARCHIVE.append(K)

The problem I am having is this: If I do:

K = []
ARCHIVE = []
ARCHIVE.append(K)

any time K is updated (user submits new input) the content of ARCHIVE
is erased:

If I do this:

K = []
ARCHIVE.append(K)

I get NameError: "Name ARCHIVE not defined"

What is the solution?

archive = []
k = ["a", "b"]
for new_k in get_container():
archive.append(k)
k = new_k

I. e. don't rebind the name archive if you don't want to lose old data.
.... for i in range(5):
.... yield [random.choice(string.ascii_lowercase) for _ in
range(2)]
....
archive = []
k = ["a", "b"]
for new_k in get_container():
.... archive.append(k)
.... k = new_k
.... print "k is now", k
.... print "archive contents", archive
....
k is now ['h', 'r']
archive contents [['a', 'b']]
k is now ['t', 'y']
archive contents [['a', 'b'], ['h', 'r']]
k is now ['y', 'q']
archive contents [['a', 'b'], ['h', 'r'], ['t', 'y']]
k is now ['p', 'i']
archive contents [['a', 'b'], ['h', 'r'], ['t', 'y'], ['y', 'q']]
k is now ['y', 'n']
archive contents [['a', 'b'], ['h', 'r'], ['t', 'y'], ['y', 'q'], ['p',
'i']]

Peter
 
D

Dennis Lee Bieber

Dennis said:
The problem I am having is this: If I do:

K = []
ARCHIVE = []
ARCHIVE.append(K)

any time K is updated (user submits new input) the content of ARCHIVE
is erased:
No, it is NOT erased... It is MUTATED...

But he rebinds the ARCHIVE name.

I interpreted that to be just a snippet extracted from the code
showing the type of statements he is using... After all, taken
literally, "K" is not updated either.
 

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

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,458
Latest member
Chris#

Latest Threads

Top