Python代码报错UnboundLocalError:sessionid未赋值即引用的问题排查
Let's break down why you're hitting this UnboundLocalError and how to fix it:
The Root Cause
The error occurs because sessionid is only assigned inside the try block, but your finally block tries to use it unconditionally. If any exception fires before the line sessionid = response.split(...) runs (for example, if the login() call fails, or the split operation can't find the expected string pattern), sessionid will never be created. When the code hits the finally block, it tries to pass an undefined variable to logout(), hence the error.
When you run the function alone, you're probably not triggering those edge-case exceptions—so sessionid gets assigned properly and the finally block works fine. But your test suite is hitting scenarios where the try block fails early.
Fixes to Implement
Here are two practical ways to resolve this:
1. Initialize sessionid before the try block
Start with a default value (like None) to ensure the variable exists even if the try block fails, then add a check before calling logout:
def addUser(loginUri, logoutUri1, logoutUri2, addUserUri, dbUri, dataMap): sessionid = None # Initialize variable outside the try block csrftoken = None try: response = login(loginUri, dataMap) sessionid = response.split("var jsessionid = '")[1].split("'")[0] csrftoken = response.split("wap.csrf_token=\"")[1].split("\"")[0] configManager = getDBData("select+instanceid+from+XGS_GROUP+where+instancename%3D%27Config+Managers%27", sessionid, csrftoken, dbUri, dataMap) nbiWrite = getDBData("select+instanceid+from+XGS_GROUP+where+instancename%3D%27NBI+Write%27", sessionid, csrftoken, dbUri, dataMap) rootDomain = getDBData("select+instanceid+from+XGS_GROUP+where+instancename%3D%27ROOT-DOMAIN%27", sessionid, csrftoken, dbUri, dataMap) addUserData = '''------WebKitFormBoundarySkroBjW9bHRdh2YW\r\nContent-Disposition''' addUserPost(addUserUri, addUserData, sessionid, csrftoken, dataMap) except Exception as err: log(str(traceback.format_exc())) dataMap["failureReason"] = "Issue in user addition" finally: # Only call logout if a valid sessionid was created if sessionid is not None: logout(logoutUri1, sessionid, dataMap)
2. Use regex for safer value extraction (bonus improvement)
Your current split() approach is fragile—small changes to the response format (like extra spaces or modified syntax) will throw an IndexError. Using regular expressions makes this extraction more robust:
import re def addUser(loginUri, logoutUri1, logoutUri2, addUserUri, dbUri, dataMap): sessionid = None csrftoken = None try: response = login(loginUri, dataMap) # Extract sessionid with regex session_match = re.search(r"var jsessionid = '([^']+)'", response) if not session_match: raise ValueError("Failed to extract sessionid from login response") sessionid = session_match.group(1) # Extract csrftoken with regex csrf_match = re.search(r"wap.csrf_token=\"([^\"]+)\"", response) if not csrf_match: raise ValueError("Failed to extract csrftoken from login response") csrftoken = csrf_match.group(1) # ... rest of your try block code ... except Exception as err: log(str(traceback.format_exc())) dataMap["failureReason"] = "Issue in user addition" finally: if sessionid is not None: logout(logoutUri1, sessionid, dataMap)
This gives you clear, actionable errors if the expected values aren't present, instead of vague runtime crashes.
Why This Only Happens in the Test Suite
Your standalone test likely runs under ideal conditions where login succeeds and the response matches your expected format. The test suite is probably validating edge cases (failed login, malformed response, network issues, etc.) that trigger exceptions in the try block before sessionid can be assigned.
内容的提问来源于stack exchange,提问作者mac

