Подтвердить что ты не робот

Локальная переменная, заданная перед назначением в Python?

Я использую библиотеку PyQt, чтобы сделать снимок экрана веб-страницы, а затем прочесть через CSV файл с разными URL-адресами. Я сохраняю переменную подачу, которая увеличивается каждый раз, когда URL-адрес обрабатывается и поэтому должен увеличиваться до количества URL-адресов.

Здесь код:

webpage = QWebPage()
fo = open("C:/Users/Romi/Desktop/result1.txt", "w")
feed = 0
def onLoadFinished(result):
    #fo.write( column1[feed])#, column2[feed], urls[feed])
   #feed = 0
   if not result:
        print "Request failed"
    fo.write(column1[feed])
    fo.write(',')
    fo.write(column2[feed])
    fo.write(',')
    #fo.write(urls[feed])
    fo.write(',')
    fo.write('404,image not created\n')
    feed = feed + 1
        sys.exit(1)
        save_page(webpage, outputs.pop(0))   # pop output name from list and save
   if urls:
        url = urls.pop(0)   # pop next url to fetch from list
        webpage.mainFrame().load(QUrl(url))
    fo.write(column1[feed])#,column2[feed],urls[feed],'200','image created','/n')
    fo.write(',')
    fo.write(column2[feed])
    fo.write(',')
    #fo.write(urls[feed])
    fo.write(',')
    fo.write('200,image created\n')
    feed = feed + 1
   else:
        app.quit()  # exit after last url

webpage.connect(webpage, SIGNAL("loadFinished(bool)"), onLoadFinished)
webpage.mainFrame().load(QUrl(urls.pop(0)))
#fo.close()
sys.exit(app.exec_())

Это дает мне ошибку:

local variable feed referenced before the assignment at fo.write(column1[feed])#,column2[feed],urls[feed],'200','image created','/n')

Любая идея, почему?

4b9b3361

Ответ 1

Когда Python анализирует тело определения функции и встречает назначение, такое как

feed = ...

Python интерпретирует feed как локальную переменную по умолчанию. Если вы не хотите, чтобы это была локальная переменная, вы должны поставить

global feed

в определении функции. Глобальный оператор не должен быть в начале определения функции, но обычно он помещается. Где бы он ни размещался, глобальная декларация делает feed глобальную переменную всюду в функции.

Без глобального оператора, поскольку feed воспринимается как локальная переменная, когда Python выполняет

feed = feed + 1,

Сначала Python оценивает правую часть и пытается найти значение фида. Первый раз через это находит feed - undefined. Отсюда ошибка.

Самый короткий способ исправить код - добавить global feed в начало onLoadFinished. Лучше всего использовать класс:

class Page(object):
    def __init__(self):
        self.feed = 0
    def onLoadFinished(self, result):
        ...
        self.feed += 1

Проблема с функциями, которые мутируют глобальные переменные, заключается в том, что это затрудняет поиск кода. Функции больше не изолированы. Их взаимодействие распространяется на все, что влияет или зависит от глобальной переменной. Таким образом, это делает более сложные программы более трудными для понимания.

Избегая мутирующих глобальных переменных, в конечном итоге ваш код будет легче понять, протестировать и поддерживать.

Ответ 2

Поместите глобальный оператор в начало вашей функции, и вы должны быть хороши:

def onLoadFinished(result):
    global feed
    ...

Чтобы продемонстрировать, что я имею в виду, посмотрите на это небольшое испытание:

x = 0
def t():
    x += 1
t()

это взрывается с вашей той же ошибкой, где:

x = 0
def t():
    global x
    x += 1
t()

нет.

Причиной этого является то, что внутри t Python считает, что x является локальной переменной. Кроме того, если вы явно не укажете, что x является глобальным, он попытается использовать локальную переменную с именем x в x += 1. Но, поскольку в локальной области t нет x, он выдает ошибку.

Ответ 3

Поскольку интерпретатор Python считывает определение функции (или, я думаю, даже блок с отступом), все переменные, назначенные внутри функции, добавляются к локалям этой функции. Если локаль не имеет определения перед назначением, интерпретатор Python не знает, что делать, поэтому он выдает эту ошибку.

Решение состоит в том, чтобы добавить

global feed

к вашей функции (обычно около вершины), чтобы указать интерпретатору, что переменная фида не является локальной для этой функции.