英文:
UnboundLocalError at ConnectionError for API call with requests
问题
我正在尝试编写一个用于处理调用API并返回JSON的函数。以下是我目前的函数代码:
import requests
def get_data(url:str, headers:str, timeout_seconds=5) -> str:
"""Return JSON file from API call."""
try:
response = requests.get(
url, headers=headers, timeout=timeout_seconds
)
response.raise_for_status()
except requests.exceptions.HTTPError as errh:
print("Http Error:", errh)
except requests.exceptions.ConnectionError as errc:
print("Error Connecting:", errc)
except requests.exceptions.Timeout as errt:
print("Timeout Error:", errt)
except requests.exceptions.RequestException as err:
print("Unspecified error:", err)
return response.json()
这段代码在请求成功时工作正常,但当尝试通过断开互联网连接来模拟错误时,我会额外收到以下错误消息。这是我在函数中处理不正确的地方吗?
UnboundLocalError: local variable 'response' referenced before assignment
英文:
I am trying to write myself a function to handle my calls to an API, which return a JSON. This is my function at the moment:
import requests
def get_data(url:str, headers:str, timeout_seconds=5) -> str:
"""Return JSON file from API call."""
try:
response = requests.get(
url, headers=headers, timeout=timeout_seconds
)
response.raise_for_status()
except requests.exceptions.HTTPError as errh:
print("Http Error:", errh)
except requests.exceptions.ConnectionError as errc:
print("Error Connecting:", errc)
except requests.exceptions.Timeout as errt:
print("Timeout Error:", errt)
except requests.exceptions.RequestException as err:
print("Unspecified error:", err)
return response.json()
This works fine when the request is successful, but when trying to simulate an error by disconnecting from the internet, I get this error additonally to the Connection Error. Is this something I'm not handling correctly in my function?
UnboundLocalError: local variable 'response' referenced before assignment
答案1
得分: 1
When the call to requests.get() throws an exception in the line response = requests.get(
url, headers=headers, timeout=timeout_seconds
)
the variable response is never assigned. This is causing the UnboundLocalError when you try to access response.json() as response has no meaning
Here is one possible solution:
import requests
def get_data(url:str, headers:str, timeout_seconds=5) -> str:
"""Return JSON file from API call."""
response = None
try:
response = requests.get(
url, headers=headers, timeout=timeout_seconds
)
response.raise_for_status()
except requests.exceptions.HTTPError as errh:
print("Http Error:", errh)
except requests.exceptions.ConnectionError as errc:
print("Error Connecting:", errc)
except requests.exceptions.Timeout as errt:
print("Timeout Error:", errt)
except requests.exceptions.RequestException as err:
print("Unspecified error:", err)
if response is None:
return None # returning {} or raising an exception are also options.
return response.json()
Depending on how you want the caller to handle this and check for no data, you could return None, an empty dict, or raise a custom Exception indicating a failure to retrieve the data.
英文:
When the call to requests.get() throws an exception in the line response = requests.get(
url, headers=headers, timeout=timeout_seconds
)
the variable response is never assigned. This is causing the UnboundLocalError when you try to access response.json() as response has no meaning
Here is one possible solution:
import requests
def get_data(url:str, headers:str, timeout_seconds=5) -> str:
"""Return JSON file from API call."""
response = None
try:
response = requests.get(
url, headers=headers, timeout=timeout_seconds
)
response.raise_for_status()
except requests.exceptions.HTTPError as errh:
print("Http Error:", errh)
except requests.exceptions.ConnectionError as errc:
print("Error Connecting:", errc)
except requests.exceptions.Timeout as errt:
print("Timeout Error:", errt)
except requests.exceptions.RequestException as err:
print("Unspecified error:", err)
if response is None:
return None # returning {} or raising an exception are also options.
return response.json()
Depending on how you want the caller to handle this and check for no data, you could return None, an empty dict, or raise a custom Exception indicating a failure to retrieve the data.
答案2
得分: 1
Return语句位于try-except块外部,如果发生异常,则响应对象不存在。将return语句放在try块内部。
或者,您可以像这样处理所有请求异常:
import requests
from typing import Optional
def get_data(url: str, headers: str, timeout_seconds: int = 5) -> Optional[str]:
"""从API调用中返回JSON文件。"""
try:
response = requests.get(url, headers=headers, timeout=timeout_seconds)
return response.json()
except requests.exceptions.RequestException as e:
print("错误:", e)
请注意,`get_data` 的返回值在发生异常时被设置为 `Optional`。
<details>
<summary>英文:</summary>
Return is located out of try-except block, if exception is occurred, then response object is not exists. Place return inside `try` block.
Or you can handle all requests exceptions like this:
import requests
from typing import Optional
def get_data(url: str, headers: str, timeout_seconds: int = 5) -> Optional[str]:
"""Return JSON file from API call."""
try:
response = requests.get(url, headers=headers, timeout=timeout_seconds)
return response.json()
except requests.exceptions.RequestException as e:
print("Error:", e)
Note, that return value of `get_data` is set to `Optional` in case of exception.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论