簡體   English   中英

為什么會出現錯誤“賦值之前引用本地變量”或“未定義全局變量”的錯誤?

[英]Why am I getting either error “local variable referenced before assignment” or “global variable not defined”?

首先,為下面很長很糟糕的代碼道歉。 它正在進行中,我將其全部粘貼了,因為可能需要運行它才能找到問題所在。

我收到錯誤代碼“分配前已引用本地變量'dennisov_type'”,我認為這是因為我試圖從外部(縮進之外)引用它。 但是,我試圖通過在if語句之前以及之后,在函數內部,函數外部,幾乎在所有地方的行上鍵入“ global dennisov_type”,使要引用的變量(dennisov_type)成為全局變量。我可以。 但是當我這樣做時,即使得到了定義,我也得到了錯誤代碼“未定義全局名稱'dennisov_type'”。

從Tkinter窗口的下拉框中選擇一個選項並按下“選擇”按鈕后,將顯示代碼。

有人介意在Python編輯器中為我運行此操作,並告訴我哪里出了問題嗎?

from Tkinter import Tk, Button, Canvas, END, Spinbox
from ttk import Progressbar, Combobox
from urllib import urlopen
from re import findall
import re
import itertools

## Create a window
window = Tk()

## Give the window a title
window.title('Watch finder')

## Types of Dennisov watches
dennisov_type_list = ['Barracuda Limited','Barracuda Chronograph',
                      'Barracuda Mechanical','Speedster','Free Rider',
                      'Nau Automatic','Lady Flower','Enigma','Number One']

dennisov_file = open('dennisov_url.html', 'w')

dennisov_file.write('''
<!DOCTYPE html>
<html>
    <head>
        <title>Watches</title>
    </head>
    <body>
''')

#### Display the quanity of watches available for each type
##quantity_box = len(watch_option)
##
#### 
##for watch, number in enumerate(watch_option):
##    watch_number_name = watch_option[number][0]
##    watch_number_image = watch_option[number][1]
##    watch_number_price = watch_option[number][2]
##    watch_number_link = watch_option[(number)][3]
####    dennisov_file.write('<h1>' + watch_number_name + '</h1>')
##    print watch_number_image
####    dennisov_file.write('<img src="' + watch_number_image + '">\n')
##    print watch_number_price
####    dennisov_file.write('<h2>' + watch_number_price + '</h2>')
##    print watch_number_link
####    dennisov_file.write('<a href="'+watch_number_link+'">'+watch_number_link+'</a>')
##       

dennisov_file.write('''
</body>
</html>
''')

## Define function for ...............
def display_choice():
    dennisov_type_selection = (dennisov_type_dropdown.get() + '\n')
    if dennisov_type_selection == 'Barracuda Limited':
        dennisov_type = 'barracuda_chronograph'
    elif dennisov_type_selection == 'Barracuda Chronograph':
        dennisov_type = 'barracuda_chronograph'
    elif dennisov_type_selection == 'Barracuda Mechanical':
        dennisov_type = 'barracuda_mechanical'
    elif dennisov_type_selection == 'Speedster':
        dennisov_type = 'speedster'
    elif dennisov_type_selection == 'Free Rider':
        dennisov_type = 'free_rider'
    elif dennisov_type_selection == 'Nau Automatic':
        dennisov_type = 'nau_automatic'
    elif dennisov_type_selection == 'Lady Flower':
        dennisov_type = 'lady_flower'
    elif dennisov_type_selection == 'Enigma':
        dennisov_type = 'enigma'
    elif dennisov_type_selection == 'Number One':
        dennisov_type = 'number_one'

    dennisov_url = 'https://denissov.ru/en/'+ dennisov_type + '/'
    dennisov_url_subpage = dennisov_url[19:]

    ## Make the html document just created equal to an opened and read URL????
    ##???????????????????????????????????????????????????????????????????
    dennisov_html = urlopen(dennisov_url).read()
    ## Replace instances of double quotation marks in the text with singles 
    ## so that the findall regex code does not get confused 
    dennisov_html = dennisov_html.replace('"', "'")

    ## Find all of the images of the watches. Each watch image starts with the text
    ## "img src=". Do not match those with any " symbols in the URL
    watch_image_urls = findall("<img src='(/files/collections/o[^']*)'", dennisov_html)
    ## Add the URL domain to each watch image subpage to create full addresses
    watch_image_urls = ['https://denissov.ru' + remainder for remainder in watch_image_urls]

    ##    dennisov_file.write('        <img src="' + image + '">\n')

    ## Return the watch type. The watch type is in a title tag called "titlusref"
    ## and can be any combination of letters and spaces, followed by a space and
    ## "<" symbol. 
    watch_type = findall("titlusref'\>([a-zA-Z]+ *[a-zA-Z]*) *\<", dennisov_html)[0]

    ## Find all of the links when each watch is clicked. Each watch link starts
    ## with the text "a href=" followed by the subpage, followed by any
    ## letter, number and "_" symbol combination, followed by a backslash
    watch_link_urls = findall("a href='" + (dennisov_url_subpage) + "([A-Za-z0-9_]+/)", dennisov_html)  
    ## Add the main URL to each watch subpage
    watch_link_urls = [str(dennisov_url) + remainder for remainder in watch_link_urls]

    ## Find all of the model numbers of each watch. Each model starts with the text
    ## "covername" then any combination of letters, dots and spaces. 
    watch_models = findall("covername'>([A-Z a-z0-9\.]+)", dennisov_html)
    ## Add the watch type to each watch model, seperated by a space, to create the
    ## full watch names
    watch_names = [str(watch_type) + " " + remainder for remainder in watch_models]

    ## Get current USD to AUD exchange rate using a known currency website
    currency_converter_url = 'http://www.xe.com/currencyconverter/convert/?From=USD&To=AUD'
    currency_html = urlopen(currency_converter_url).read()
    ## Replace instances of double quotation marks in the text with singles 
    ## so that the findall regex code does not get confused 
    currency_html = currency_html.replace('"', "'")
    ## Find the exchange rate. The exchange rate starts with "uccResultAmount'>"
    ## and is then followed by any combination of numbers with a decimal place
    exchange_rate = float(findall("uccResultAmount'\>([0-9]+\.[0-9]*)", currency_html)[0])

    ## Find the price of the models and make into floats. Each model price contains
    ## numbers followed by the text "USD"
    USD_watch_price = [float(price) for price in (findall("([0-9]*) usd", dennisov_html))]
    ## Convert the USD watch prices to current AUD prices and round to 2 decimals
    watch_price = [round(exchange_rate*price, 2) for price in USD_watch_price]
    ## Add the currency to the prices
    watch_price = ["AU $" + str(price) for price in watch_price]

    ## Match each watch name to its image and URL inside a tuple and place each
    ## tuple inside a list
    watch_list = zip(watch_names, watch_image_urls, watch_price, watch_link_urls)
    ## For each watch tuple (matching image, name and URL), assign a watch number
    watch_option = {'watch_{}'.format(i): e for i, e in enumerate(watch_list)}

## Create a spinbox 
    spinbox_list = []
    spinbox_grid_list = []
    for watch, number in enumerate(watch_names):
        spinbox = 'spinbox_' + str(watch) + ' = Spinbox(window, width = 5, from_=0, to=10)'
        spinbox_grid = 'spinbox_' + str(watch) + '.grid(padx = 2, pady = 2, row = ' + str(1+ 4*watch) +', column = 0)'
        spinbox_list.append(spinbox)
        spinbox_grid_list.append(spinbox_grid)
        spinbox_option = {'spinbox_{}'.format(i):e for i, e in enumerate(spinbox_list)}
    spinbox_option_string = '\n'.join(spinbox_option.values())
    spinbox_grid_option = {'spinbox_grid_{}'.format(i):e for i, e in enumerate(spinbox_grid_list)}
    spinbox_grid_option_string = '\n'.join(spinbox_grid_option.values())
    exec(spinbox_option_string)
    exec(spinbox_grid_option_string)

## Create the dropdown box for the Dennisov watch types
dennisov_type_dropdown = Combobox(window, width = 25,
                                  values = dennisov_type_list)

## Create the Dennisov model selection canvas
dennisov_model_selection = Canvas(window, width = 400, height = 500,
                                  bg = 'white')

## Create Dennisov type selection button
dennisov_select_button = Button(window, text = 'Select',
                                command = display_choice)

## Locate elements on grid
dennisov_type_dropdown.grid(pady = 2, padx = 2, row = 0, column = 1)
dennisov_model_selection.grid(padx = 2, pady = 2, row = 1,
                              column = 0, rowspan = 15, columnspan = 3)
dennisov_select_button.grid(pady = 2, padx = 2, row = 0, column = 2)

dennisov_file.close()
window.mainloop()

您所有的dennisov_type_selection == ...條件都不會評估為True dennisov_type_selection始終以換行符結尾,您要與之進行比較的所有字符串都不以換行符結尾。

由於沒有條件執行,因此沒有為dennisov_type分配任何dennisov_type ,因此dennisov_url = 'https://denissov.ru/en/'+ dennisov_type + '/'失敗,並"local variable 'dennisov_type' referenced before assignment"local variable 'dennisov_type' referenced before assignment

嘗試將分配更改為

dennisov_type_selection = dennisov_type_dropdown.get()

您還應該在if-elif塊中添加else子句,以處理當用戶輸入您不期望的內容時發生的情況。 崩潰或顯示有用的消息,或者提早從函數返回,或者分配某種后備值。

elif dennisov_type_selection == 'Number One':
    dennisov_type = 'number_one'
else:
    raise Exception("Did not recognize selection: {}".format(repr(dennisov_type_selection)))

要么

elif dennisov_type_selection == 'Number One':
    dennisov_type = 'number_one'
else:
    return

要么

elif dennisov_type_selection == 'Number One':
    dennisov_type = 'number_one'
else:
    dennisov_type = 'unknown'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM