英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论