How to make a variable inside a try/except block public?

x0x picture x0x · Sep 4, 2014 · Viewed 65k times · Source

How can I make a variable inside the try/except block public?

import urllib.request

try:
    url = "http://www.google.com"
    page = urllib.request.urlopen(url)
    text = page.read().decode('utf8')
except (ValueError, RuntimeError, TypeError, NameError):
    print("Unable to process your request dude!!")

print(text)

This code returns an error

NameError: name 'text' is not defined

How can I make the variable text available outside of the try/except block?

Answer

chepner picture chepner · Sep 4, 2014

try statements do not create a new scope, but text won't be set if the call to url lib.request.urlopen raises the exception. You probably want the print(text) line in an else clause, so that it is only executed when there is no exception.

try:
    url = "http://www.google.com"
    page = urllib.request.urlopen(url)
    text = page.read().decode('utf8')
except (ValueError, RuntimeError, TypeError, NameError):
    print("Unable to process your request dude!!")
else:
    print(text)

If text needs to be used later, you really need to think about what its value is supposed to be if the assignment to page fails and you can't call page.read(). You can give it an initial value prior to the try statement:

text = 'something'
try:
    url = "http://www.google.com"
    page = urllib.request.urlopen(url)
    text = page.read().decode('utf8')
except (ValueError, RuntimeError, TypeError, NameError):
    print("Unable to process your request dude!!")

print(text)

or in the else clause:

try:
    url = "http://www.google.com"
    page = urllib.request.urlopen(url)
    text = page.read().decode('utf8')
except (ValueError, RuntimeError, TypeError, NameError):
    print("Unable to process your request dude!!")
else:
    text = 'something'

print(text)