It is a scoping thing, or rather, the lack of a scope. Python does not have block scopes; the only thing that defines a new scope in Python is a function definition. (Comprehensions do, too, but that's because they are implemented using anonymous functions.)

There is no "local" x in either the try block or the except block; both are the same x as defined before the try statement.

One exception: e is kind of local. It's still in the same scope as x, but it is unset by the try statement once it completes to avoid a reference cycle, just as if you had written del e immediately after the statement.

Answer from chepner on Stack Overflow
🌐
Python
bugs.python.org › issue43458
Issue 43458: Tutorial should mention about variable scope in try/except/finally - Python tracker
March 10, 2021 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/87624
Discussions

assign a global variable in try/except
If you are trying to change a global variable from an inner scope, then in that inner scope you need to have global company. Sometimes it can't be avoided but doing so is usually a "code smell" More on reddit.com
🌐 r/learnpython
5
1
September 7, 2017
Scope of a variable
In most cases this would be true but try blocks are an exception to the rule in that they do not create their own scope. Instead, those two variables would end up in the scope of the add function. More on teamtreehouse.com
🌐 teamtreehouse.com
2
February 18, 2018
Python variable scope within try/except blocks - Stack Overflow
I'm getting error : UnboundLocalError: local variable 'process' referenced before assignment on the code below - how do I get the process object within the except block? try: process = subpr... More on stackoverflow.com
🌐 stackoverflow.com
September 3, 2014
Does this try/except behaviour make any sense?
I hadn't tried this before, but what it seems happens is that as creates and removes the variable name for its scope. So you enter the first except block and it adds error to the local namespace. Then you enter the second except block for the IndexError and that adds error to the local scope. Then you leave that except block and it removes error from the local scope. Then you try to use error but the previous step had "cleaned it up" and so it's not in your local namespace any more. Given that, if you want to keep track of the error you'll have to use some variable other than the one you define in as to hold it. More on reddit.com
🌐 r/learnpython
8
3
February 16, 2023
Top answer
1 of 3
145

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)
2 of 3
10

As answered before there is no new scope introduced by using try except clause, so if no exception occurs you should see your variable in locals list and it should be accessible in current (in your case global) scope.

print(locals())

In module scope (your case) locals() == globals()

🌐
Reddit
reddit.com › r/learnpython › assign a global variable in try/except
r/learnpython on Reddit: assign a global variable in try/except
September 7, 2017 -

Hej guys. I have a problem assign a global variable inside a try/except. The try/except is in the main function and iam using the variable in another function. when i print the variable outside the main function i get "something" instead of the assigned value. how can i solve it?

company ="something"  #global variable

               try:
                    loggInThisFile = open(reportFilePath,'w')
                except Exception as e:
                    print("can't create report file:", reportFilePath)
                else:
                    company = link.split(" ; ")[1]
                    print(company)     #prints assigned value 

ps: the declaration and assignation is done before it soposed to be used.
Thanks in advance

🌐
DEV Community
dev.to › andrewchaa › python-try-blocks-a-breath-of-fresh-air-for-variable-scope-unlike-java-c-1k6l
Python `try` Blocks: A Breath of Fresh Air for Variable Scope (Unlike Java & C#!) - DEV Community
March 10, 2025 - This is in stark contrast to languages like Java and C#. In those languages, variables declared inside a try block are typically scoped only to that block. If you want to use them outside, you often need to declare the variable before the try block and then potentially assign it within, just to make it accessible later. This adds extra lines of code and can feel unnecessarily verbose. Let's see how Python's approach shines in practice: try: value = "Hello, World!" # Variable defined inside try except Exception as e: print(f"An error occurred: {e}") # `value` is immediately accessible here!
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › does this try/except behaviour make any sense?
r/learnpython on Reddit: Does this try/except behaviour make any sense?
February 16, 2023 -

Dear Pythonistas, I am getting more experience using try/except but I have a situation where Python appears to behave weirdly IMO.

My (a bit complex) code where I work with connection errors can be reduced to an equivalent small example:

try:
    1 / 0
except ZeroDivisionError as error:
    try:
       [1, 2, 3][3]
    except IndexError as error:
        pass
    print("The last error was:", error)

Wouldn't you also expect it to print the index error? It doesn't! Instead, a NameError for the variable error is thrown. Does anybody understand why?

I have a few more details on a Stack Overflow post where you are welcome to answer if you are looking for reputation in there:

https://stackoverflow.com/questions/75473452/why-is-python-throwing-a-nameerror-when-doing-nested-exceptions-with-same-variab

🌐
Reddit
reddit.com › r/learnpython › help: can you create a variable that is a try/exception block?
r/learnpython on Reddit: Help: Can you create a variable that is a try/exception block?
January 9, 2022 -

I have some code that pulls stock information into an excel sheet using the tickers present in the excel file, and I recently am trying to expand this code to pull in the stocks sectors using yfinance. The issue is that some of my tickers are EFT's, which do not have sectors. So whenever my code tries to run, it will throw a syntax error when it reaches an EFT stock. If I take out all the EFT's, it runs just fine.

What I'm trying to do is set my variable (sector) as a try/exception block, but I don't know if this is possible. Could someone please help me out on this? Examples or suggestions? I'm not exactly new to Python, but I'm not a regular program either. Just really lost and in hard core struggle mode on this one.

Excerpt from my code below, along with what I'm having trouble with developing below that.

import xlwings as xw
from yahoofinancials import YahooFinancials
import pandas as pd
import yfinance as yf

def main():
    wb = xw.Book.caller()
    sheet = wb.sheets[0]
    df = pd.DataFrame()
    tickers = sheet.range("D7").options(expand='down').value
    for ticker in tickers:
        find_sector = yf.Ticker(ticker)
        sector = find_sector.info['sector']

        new_row = {
            "GICS Sector": sector,
        }
        df = df.append(new_row, ignore_index=True)
    sheet.range("E6").options(index=False).value = df

if __name__ == "__main__":
    xw.Book("dividends.xlsm").set_mock_caller()
    main()

What I'm envisioning/trying/struggling with for setting my 'sector' variable:

sector =
    try:
        find_sector.info['sector']
    else:
        print('EFT')
🌐
GitHub
github.com › python › cpython › issues › 87624
Tutorial should mention about variable scope in try/except/finally · Issue #87624 · python/cpython
March 10, 2021 - assignee = None closed_at = None created_at = <Date 2021-03-10.05:08:31.470> labels = ['type-feature', '3.9', 'docs'] title = 'Tutorial should mention about variable scope in try/except/finally' updated_at = <Date 2021-03-12.19:47:11.330> user = 'https://bugs.python.org/deekox' bugs.python.org fields: activity = <Date 2021-03-12.19:47:11.330> actor = 'eric.araujo' assignee = 'docs@python' closed = False closed_date = None closer = None components = ['Documentation'] creation = <Date 2021-03-10.05:08:31.470> creator = 'deekox' dependencies = [] files = [] hgrepos = [] issue_num = 43458 keywords
Author: python
🌐
Julia Programming Language
discourse.julialang.org › general usage
Confusion about scope in try-catch blocks - General Usage - Julia Programming Language
June 11, 2024 - Regarding scoping rules this used to trip me up a bit: Python: >>> try: ... x = 2 ... except: ... pass ... >>> x 2 Julia: julia> try x = 2 catch end 2 julia> x ERROR: UndefVarError: `x` not defined
🌐
Medium
gaitatzis.medium.com › stop-using-try-catch-in-python-2c8f55870372
Stop using Try/Catch in Python. An introduction to Safe Assignment in… | by Adonis Gaitatzis | Medium
December 10, 2024 - def to_safe_assign(function, *args, **kwargs): try: output = function(*args, **kwargs) return output, None except Exception as e: return None, e · Now, to_safe_assign will capture any exception and return it as the error part of a tuple. Simplifies Error Processing: Flattening the if/else stack makes error handling direct and leaves the main logic to run without interruption. Scoped Variables: output is defined in the same scope as the rest of your function, making the code cleaner and easier to follow.
🌐
Reddit
reddit.com › r/learnpython › scope 'of except exception as e'
r/learnpython on Reddit: Scope 'of except Exception as e'
November 20, 2017 - Does e remain accessible in the 2nd print statement, or is it just localised within the try-except scope? try: foo() except Exception as e: print('Inside try-except:',e) print('Outside try-except:',e) Share ... No. (But you could set another variable inside the except block to e and its value will be retained if it was defined outside the these blocks) ... Thank you! I wanted to check this was the case, before trawling through all other areas of my code. ... This is an interesting little quirk of Python, it's not that the e has scope within the block it's that is actually deleted!
🌐
Python
docs.python.org › 3.4 › reference › executionmodel.html
4. Execution model — Python 3.4.10 documentation
April 3, 2010 - If a variable is used in a code block but not defined there, it is a free variable. Each occurrence of a name in the program text refers to the binding of that name established by the following name resolution rules. A scope defines the visibility of a name within a block.
🌐
Python.org
discuss.python.org › ideas
Should except handlers save/restore the prior value of the capture variable instead of deleting it? - Ideas - Discussions on Python.org
May 10, 2023 - Currently if you have the code: e = 1 try: ... except Exception as e: ... print(e) It will print 1 if no exception is raised, but if an exception is raised, it will raise NameError (UnboundLocalError inside a function) on the print(e) line.