Сброс переменной класса 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 переменная.

Другие вопросы по тегам