Сброс переменной класса Python?
У меня возникла эта проблема сейчас, поэтому у меня есть HTMLParser, использующий класс библиотеки HTMLParser, как это
class MyHTMLParser(HTMLParser):
temp = ''
def handle_data(self, data):
MyHTMLParser.temp += data
Мне нужна временная переменная, потому что мне нужно сохранить данные в другом месте, чтобы я мог оценить в другом месте.
Мой код использования класса выглядит следующим образом:
for val in enumerate(mylist):
parser = HTMLParser()
parser.feed(someHTMLHere)
string = parser.temp.strip().split('\n')
Проблема в том, что эта временная переменная хранит все, что я сохраняла раньше, она не сбрасывается, даже если я объявляю новый экземпляр парсера каждый раз. Как мне очистить эту переменную??? Я не хочу, чтобы это спасло все, что там было из предыдущего цикла
3 ответа
Как уже говорили другие, проблема в том, что вы добавляете данные в переменную класса вместо переменной экземпляра. Это происходит из-за линии MyHTMLParser.temp += data
Если вы измените его на self.temp += data
он будет изменять данные каждого экземпляра, а не хранить их в классе.
Вот полный рабочий скрипт:
from html.parser import HTMLParser
class MyHTMLParser(HTMLParser):
temp = ""
"""Personally, I would go this route"""
#def __init__(self):
# self.temp = ""
# super().__init__()
"""Don't forget the super() or it will break"""
def handle_data(self, data):
self.temp += data # <---Only real line change
"""TEST VARIABLES"""
someHTMLHere = '<html><head><title>Test</title></head>\
<body><h1>Parse me!</h1></body></html>'
mylist = range(5)
""""""""""""""""""
for val in enumerate(mylist):
parser = MyHTMLParser() #Corrected typo from HTML to MyHTML
parser.feed(someHTMLHere)
string = parser.temp.strip().split('\n')
print(string) #To Test each iteration
temp
в вашем коде есть class attribute
, он будет только инициализирован, когда в первый раз python interpreter
увидеть этот класс, так temp = ''
будет работать только один раз.
Итак, переместите его в __init__
сделать это как object attribute
это хорошее решение.
Но, если вы настаиваете на том, чтобы позволить class attribute
так же, как вы сказали в комментариях:
Есть ли способ объявить глобальную переменную, которая может использоваться внутри класса и в других местах?
Кстати, это нельзя назвать global variable
, это class attribute
,
Затем вы должны были сбросить его самостоятельно. В вашем коде handle_data
как обратный вызов будет вызываться feed
несколько раз, поэтому нет никаких шансов сделать это в handle_data
Вы должны были сделать это вне класса.
Для вашего кода это может быть что-то вроде lineA
Просто к вашему сведению:
class MyHTMLParser(HTMLParser):
temp = ''
def handle_data(self, data):
MyHTMLParser.temp += data
for val in enumerate(mylist):
parser = MyHTMLParser()
MyHTMLParser.temp = '' # lineA
parser.feed(someHTMLHere)
string = parser.temp.strip().split('\n') # lineB
Увидеть lineA
, это сбросит temp
очистить, чтобы каждый экземпляр не влиял друг на друга, даже если вы объявите его в начале класса так, как вам нужно.
Но, обратите внимание, вы не должны заменить lineA
с parser.temp = ''
или назначить любое значение parser.temp
, Это сделает новый object attribute
с именем temp
, затем parser.temp
в lineB
больше не будет использовать class attribute
больше, что делает вашу цель не достижимой.
Это происходит потому, что каждый раз, когда вы звоните MyHTMLParser.temp
вы получаете новую переменную (''
).
Что вам нужно сделать, это добавить temp
к самому объекту. Вы делаете это в конструкторе:
class MyHTMLParser(HTMLParser):
def __init__(self):
self.temp = ''
def handle_data(self, data):
self.temp += data
# use a getter
def get_temp(self):
return self.temp
Теперь temp
Переменная принадлежит самому объекту. И если у вас есть несколько MyHTMLParser
объекты, у каждого из них будут свои temp
переменная.