错误局部变量在赋值前被引用



我是stackoverflow社区的新手,也是一般编程的新手。我的第一个项目是建立一个网络爬虫,看看我是否可以收集市场数据。在尝试构建它时,我一直遇到未绑定的本地错误。我知道这与我如何实例化我的类以及如何引用变量、强文本但不确定如何对其进行故障排除有关。

class Stock:
def __init__(self,symbol,company):
self.symbol = symbol
self.company = company
self.data = []



def query_stock_symbol(self):
wait_time = round(max(5, 10 +random.gauss(0,3)), 2)
time.sleep(wait_time)


url = 'https://www.barrons.com/quote/stock/us/xnys/%s?mod=DNH_S'  % (self.symbol)
page = requests.get(url)
if page.status_code == 403 or page.status_code == 404:
url = 'https://www.barrons.com/quote/stock/us/xnas/%s?mod=DNH_S' % (self.symbol)

user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
headers = {'User-Agent': user_agent}
req = urllib.request.Request(url,headers=headers)

try:
response = urllib.request.urlopen(req)
except urllib.error.URLError as e:
print(e.reason)

self.soup = BeautifulSoup(response, 'html.parser')


#         Finding stock price
for a in self.soup.findAll('span',{'class':'market_price'}):
stock_price_str = a.text.replace(',','')
if stock_price_str != 'N/A':
self.stock_price = float(stock_price_str)
else:
self.stock_price = None

我收到的错误是这样的

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-277-f9c756bf109f> in <module>
1 x = Stock('CRM','Salesforce')
----> 2 x.query_stock_symbol()
3 
<ipython-input-276-1f910b91d713> in query_stock_symbol(self)
26             print(e.reason)
27 
---> 28         self.soup = BeautifulSoup(response, 'html.parser')
29 
30 
UnboundLocalError: local variable 'response' referenced before assignment
```

Thanks for all your time and consideration, I really do appreciate it

这是因为当您尝试在该块之外使用它时,您responsetry块中声明,您可以:

1-在try块中使用之前全局声明response,如下所示:

try:
global response
response = ...
except ...:
...
self.soup = ....

2-在response赋值下方的try块内实例化Soup对象,如下所示:

try:
response = ...
self.soup = BeautifulSoup(response, 'html.parser')

3-在try块之前声明response变量,这是一种更成问题的方法,并且在未正确分配响应时(例如当exception被提出时)可能会导致问题,但是如果您决定这样做,您可以执行以下操作:

response = None
try:
response = ...
except ...:
.....
self.soup = ...

永远记住,本地声明的变量,如try块、if块、else块等,在所述块之外无法访问,它们是该本地变量

你应该处理urllib.request.urlopen引发的错误:如果此方法引发错误,你只打印它并继续执行你的代码。但是,这意味着 try 块中的所有指令可能尚未执行,并且response尚未定义。

例如,此代码按预期工作:

try:
a = 10
except Exception:
print(e)
print(a)

输出为:

10

因此,变量a是在打印时定义的;另一方面,此代码会引发一个错误,类似于您正在试验的错误:

try:
a = 10 / 0
except Exception as e:
print(e)
print(a)
division by zero
Traceback (most recent call last):
File "try_catch_example.py", line 6, in <module>
print(a)
NameError: name 'a' is not defined

因此,真正的问题是,当try块中的某些内容失败时,您必须决定该怎么做。

在您的情况下,打印错误是不够的;您可能应该中断该方法,引发警告或重新引发更"注释"的错误:

try:
response = urllib.request.urlopen(req)
except urllib.error.URLError as e:
print('Something wrong with urlopen! Read carefully the reason of the error')
print(f'req: {req}')
print(e.reason)
raise RuntimeError('Failed to open the required url') from exc

最新更新