Reputation: 358
I've got a pretty good understanding of python's try-except clause, but I'm encountering problems when trying to put it inside of a function.
>>> def tryAppend(child, parent):
... try:
... parent.append(child)
... except NameError:
... print "WRONG NAME"
>>> var1 = []
>>> var2 = 'test2'
>>> tryAppend(var2, var1) #works, no error
>>> tryAppend(foo, var1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
it is almost like python doesn't see the try: statement. Any help is appreciated.
Upvotes: 6
Views: 53193
Reputation: 1
def tryAppend(child, parent):
try:
global temp_list
temp_list = [child]
script = "global " + str(parent) + '\n' + str(parent) + " = " + str(parent) + " + temp_list" + '\n' + "print('List already exists, only append')"
return exec(script)
except NameError:
print("List does not exist, creating list")
string_e_1 = "global " + str(parent) + '\n' + str(parent) + " = temp_list"
return exec(string_e_1)
Upvotes: 0
Reputation: 43
(Duplicates of this question also here and here)
In Python 3, you can avoid this issue by passing a lambda function into the function containing the try-except. For example, this first block will throw an error:
def trying_fn1(foo):
try:
print(foo)
except ZeroDivisionError:
print('Cannot divide a number by zero.')
trying_fn1(10/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module> trying_fn1(10/0)
ZeroDivisionError: division by zero
But this next function accepts a lambda function which it executes inside the try-except:
def trying_fn2(lambda_foo):
try:
print(lambda_foo())
except ZeroDivisionError:
print('Cannot divide a number by zero.')
lambda_foo = lambda: 10/0
trying_fn2(lambda_foo)
Cannot divide a number by zero.
Hope this helps! If there's a new or better way to do this, happy to take suggestions!
Upvotes: 1
Reputation:
tryAppend(foo, var1)
is evaluated (roughly) in this order:
tryAppend
referencesfoo
referencesvar1
referencestryAppend
does, uncluding the try-except)The error occurs at #2, long before the function and the try block is entered. In fact, the try block cannot to throw a NameError, as the only names used are parent
and child
, both being arguments and thus always available (if .append
does not exist, that's an AttributeError
).
In the same way, the following code will not print "caught it" because the exception is raised before the try block is executed:
raise Exception("Catch me if you can")
try:
pass # do nothing
except:
print "caught it"
Upvotes: 11
Reputation: 1083
For someone who is looking for how to use try except construction inside of the function. I am not sure whether it is a good programming style, but it works.
You can put string arguments to the function. It will be evaluated correctly and then you can use exec
inside of the function:
def tryAppend(child, parent):
try:
script = parent + '.append(' + child + ')'
exec script
return parent
except NameError:
print "WRONG NAME"
var1 = []
var2 = 'test2'
tryAppend('var2', 'var1')
tryAppend('foo', 'var1')
Upvotes: 1
Reputation: 73588
foo
exception happens even before you enter the function tryAppend()
i.e. outside of the function.
Upvotes: 1
Reputation: 19037
The NameError is being thrown when the name 'foo' is evaluated, which is before entering the function. Therefore the try/except within the function isn't relevant.
Upvotes: 2
Reputation: 6647
The name error is happening before it ever gets into tryAppend. It evaluates the value of foo when trying to pass it to the function. This works:
def tryAppend(child, parent):
parent.append(child)
var1 = []
try:
tryAppend(foo, var1)
except NameError:
print 'WRONG NAME'
Upvotes: 5
Reputation: 3114
This has nothing to do with your exception handler. The error you are seeing is because "foo" is not defined anywhere.
Upvotes: 5