Django/Python - Try/except problem - python

i have code like this:
try:
var = request.POST['var']
except NameError:
var = ''
Why always code after "except" is executing? Even if request.POST['var'] exist.

How do you know it is executing? Perhaps request.POST['var'] is also '' so you couldn't tell the difference.
Also, the only way that
var = request.POST['var']
could raise a NameError is if request doesn't exist.
If request.POST doesn't exist, means POST doesn't exist as an attribute of request thus raising AttributeError instead, and if request.POST['var'] doesn't exist, means 'var' is not a key of request.POST thus raising KeyError instead.
EDIT:
My guess is that you're not sending a POST. But can't know for sure.

Eliminate the guesswork and replace NameError with something like KeyboardInterrupt, look at the traceback and you'll know exactly what the problem is.

A better way to do what you seem to be trying to do might be
var = request.POST.get('var', 'some default value')
where the second argument to the POST dict's get method is the value to return if the key ('var' in this case) doesn't exist. Translating your example exactly would result in:
var = request.POST.get('var', '')
That way, no try...except block or conditional statements are needed.

what's the result of the following in your case?
except NameError, e:
print e

try
try:
if request.method == 'POST':
var = request.POST['var']
except NameError:
var = ''

Related

Elegant design to report status on whether a function returned exception or values as status

I have this code structure:
#########file1.py#############
def newsCSVwriter(fileName):
try:
newsCleaner(fileName)
except Exception as e:
print "Exception: ", e
########file1.py#############
def newsCleaner(newsFile):
....
#########file2.py###########
try:
df1['newsFile'].apply(newsCSVwriter)
except Exception as e:
print "exception:",e
I want to write a csv that has a status column value of yes or no depending on whether newsCleaner(fileName) returns a value or exception. Should I implement the logic in file1 or file2? Also, an example will be great.
Assuming you don't actually need the returned value, in your newCSVWriter function do this:
try:
newsCleaner(fileName)
except:
return 'no'
else:
return 'yes'
How you structure your code in terms of files is dependant on what all of it does, but you've only posted part of it.
Stylistically I would rename them to something more informative than 'file1' and 'file2'. I would also have the function return a bool (True or False) instead, but that's up to you.

Preventing python from terminating if json data not found

While iterating through json there are some files which does not have the field i am parsing (using iterator as test_category_list = [info["Test Caps"][0]] ). Python is terminating the execution with error KeyError: 'Test Caps' . I wanted give a default test_category_list if no key found. How I will do that in python ?
dict.get(key[, default]) accepts a second argument that is returned if no key is found (you can return any python object; for the example i return the string 'no_key_found'):
dct = {'key': 'value'}
print(dct.get('key', 'no_key_found')) # -> 'value'
print(dct.get('no_key', 'no_key_found')) # -> 'no_key_found'
or you catch the KeyError in a try/except block:
try:
ret = dct['key']
except KeyError:
ret = 'no_key_found'
note: be sure to only catch the KeyError and not any other kind of exception that might occur there.
you could also check if the key exists before you access it (if 'key' in dct: ...); this is discouraged: the common python coding style prefers EAFP over LBYL.
One option is to use exceptions. They attempt to run the code in the 'try' section, and if that fails they run the except and continue through the script.
try:
test_category_list = [info["Test Caps"][0]]
except Keyerror:
test_category_list = 'error'

Python: Break-up large function into segments

I am creating a Bot for Reddit. I currently only have 1 very large function and I am looking to create sub-functions to make it more readable.
Here is a rough break-down of what it does
def replybot():
submissions = reversed(list(subreddit.get_new(limit=MAXPOSTS)))
for post in submissions:
try:
author = post.author.name
except AttributeError:
print "AttributeError: Author is deleted"
continue # Author is deleted. We don't care about this post.
# DOES PID EXIST IN DB? IF NOT ADD IT
cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
sql.commit()
if cur.fetchone(): # Post is already in the database
continue
cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
sql.commit()
...
I am looking to break the code up into segments i.e. put
try:
author = post.author.name
except AttributeError:
print "AttributeError: Author is deleted"
continue # Author is deleted. We don't care about this post.
in it's own function and call it from within replybot() but I run into the issue of calling continue. I get SyntaxError: 'continue' not properly in loop
Is there a way for me to do this?
If you take the inner part of a loop and convert it to its own function, it's no longer in a loop. The equivalent of continue in a loop, for a function, is return (i.e. terminate this iteration (which is now a function call) early).
Raise the error again instead of trying to continue. Either simply let it bubble to the main loop, or if you need better error handling, make your own custom error. For instance:
class MyNotFatalError(Exception):
pass
def do_something():
try:
a, b, c = 1, 2
except ValueError:
raise MyNotFatalError('Something went wrong')
# In your main function
for post in submissions:
try:
do_something()
do_some_other_thing()
do_some_more()
except MyNotFatalError as err:
continue # we could print out the error text here
do_some_last_thing()
It is probably better that way because you only catch errors you know you want to catch, and still let the program crash when there are actual bugs.
If you had simply caught ValueError that would also intercept and hide all other possible sources of the same kind of error.
as Claudiu said, when you broke inner commands into it's own function; It's not no longer in the loop and your code will be look like this:
def isNotAuthorDeleted(post):
try:
author = post.author.name
return author
except AttributeError:
print "AttributeError: Author is deleted"
return false
and your loop will be:
for post in submissions:
if not isNotAuthorDeleted(post):
continue

Which key failed in Python KeyError?

If I catch a KeyError, how can I tell what lookup failed?
def poijson2xml(location_node, POI_JSON):
try:
man_json = POI_JSON["FastestMan"]
woman_json = POI_JSON["FastestWoman"]
except KeyError:
# How can I tell what key ("FastestMan" or "FastestWoman") caused the error?
LogErrorMessage ("POIJSON2XML", "Can't find mandatory key in JSON")
Take the current exception (I used it as e in this case); then for a KeyError the first argument is the key that raised the exception. Therefore we can do:
except KeyError as e: # One would do it as 'KeyError, e:' in Python 2.
cause = e.args[0]
With that, you have the offending key stored in cause.
Expanding your sample code, your log might look like this:
def poijson2xml(location_node, POI_JSON):
try:
man_json = POI_JSON["FastestMan"]
woman_json = POI_JSON["FastestWoman"]
except KeyError as e:
LogErrorMessage ("POIJSON2XML", "Can't find mandatory key '"
e.args[0]
"' in JSON")
It should be noted that e.message works in Python 2 but not Python 3, so it shouldn't be used.
Not sure if you're using any modules to assist you - if the JSON is coming in as a dict, one can use dict.get() towards a useful end.
def POIJSON2DOM (location_node, POI_JSON):
man_JSON = POI_JSON.get("FastestMan", 'No Data for fastest man')
woman_JSON = POI_JSON.get("FastestWoman", 'No Data for fastest woman')
#work with the answers as you see fit
dict.get() takes two arguments - the first being the key you want, the second being the value to return if that key does not exist.
If you import the sys module you can get exception info with sys.exc_info()
like this:
def POIJSON2DOM (location_node, POI_JSON):
try:
man_JSON = POI_JSON["FastestMan"]
woman_JSON = POI_JSON["FastestWoman"]
except KeyError:
# you can inspect these variables for error information
err_type, err_value, err_traceback = sys.exc_info()
REDI.LogErrorMessage ("POIJSON2DOM", "Can't find mandatory key in JSON")

Python error exception handling with less return statements?

I have a function with a try catch block where I have:
def testfunction():
try:
good = myfunction()
return good
except ExceptionOne:
error="Error ExceptionOne".
return error
except ExceptionTwo:
error="Error ExceptionTwo".
return error
except ExceptionThree:
error="Error ExceptionThree".
return error
Is there a way such that I could structure this in such a way where have a single return statement for all the exceptions?
What about something like:
def testfunction():
try:
good = myfunction() # or `return myfunction()` if the case is actually this simple
except (ExceptionOne, ExceptionTwo, ExceptionThree) as err:
error = 'Error %s' % err.__class__.__name__
return error
return good
Of course, I'm not exactly sure what the purpose of this is. Why not just let the exception propogate and handle it higher up? As it is, you need logic to check the return value to see if it's good or not anyway, I think it would be cleaner if that logic was bound up in exception handling rather than in type checking or string value checking ...

Categories

Resources