Переменная класса отказывается работать через "self", но работает с именем класса (Python) - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть простой класс и переменная класса внутри этого класса:

class QuotesToScrape:

    authors_list = []

    def __init__:

В этом классе есть строка кода в методе (метод вызывается из init ):

def gather_authors_list(self):
    self.authors_list = some_value

Эта строка не работает, переменная author_list по-прежнему пуста. Но если я изменю «self» на имя класса, все будет работать нормально:

def gather_authors_list(self):
    QuotesToScrape.authors_list = some_value

Декораторы не используются. Я чувствую, что вот какой-то важный трюк, который мне нужно понять, чтобы не допустить серьезных проблем в будущем. Важная часть: у меня есть еще одна переменная класса, "кавычки", и она прекрасно работает. Вот почти полный фрагмент моего кода. Переменная класса "quotes" в порядке, переменная класса "hors_list "не в порядке.

class QuotesToScrape:

    quotes = []         
    authors_list = []   

    def __init__(self):
        for page_number in range(1, 501):
            page_url = self.make_page_url(page_number)
            soup = self.get_soup(page_url)
            if self.out_of_quotes(soup):
                break
            quote_blocks = self.parse_quotes(soup)
            for quote_block in quote_blocks:self.quotes
                quote = self.extract_quote(quote_block)
                self.quotes.append(quote)
        self.gather_authors_list()

...

    def gather_authors_list(self):
        authors = list(set([quote.get('Author') for quote in self.quotes]))
        if 'Alexandre Dumas fils' in authors:
            duma_index = authors.index('Alexandre Dumas fils')
            authors[duma_index] = 'Alexandre (fils) Dumas'
        self.authors_list = sorted(authors, key = lambda x: x.split(" ")[-1])

Добавлено позже. Задача решена. Изменена последняя строка для соответствия направлениям из комментариев. Это решило мою проблему, теперь метод не создает новую переменную, а использует существующую пустую переменную класса:

self.authors_list.extend(sorted(authors, key = lambda x: x.split(" ")[-1]))

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

Проблема в том, что ваш код создает две переменные:

одну в пространстве имен класса

class QuotesToScrape:

    authors_list = []

, а другую в пространстве имен объекта.

def gather_authors_list(self):
    self.authors_list = some_value

Переменные определяются присваиванием в python. Поэтому, где вы их назначаете, имеет значение.

Обратите внимание, что из экземпляра объекта через self вы все равно можете достичь переменной класса: если она не найдена в пространстве имен объекта, имя ищется вкласс 'пространство имен (и суперклассы')

0 голосов
/ 04 ноября 2019

Отредактировано после рассматриваемой редакции: когда вы говорите self.authors_list = ..., переменная класса не обновляется, вместо этого создается новая переменная объекта, и она доступна только для этого экземпляра класса. В случае quotes вы выполняете любое присваивание, и вместо этого вы делаете добавление, которое отражается в переменной класса quotes.

Когда вы вместо этого сделали QuotesToScrape.authors_list, вы изменили переменную класса, и это отражение отразится на других экземплярах объекта, которые вы создадите впоследствии.

Попробуйте разобраться в вашем случае с этим примером:

class Yes:
    a = 1
    def __init__(self):
        pass

    def yes(self):
        if Yes.a==1:
            print "Yes"
        else:
            print "No, but yes"

class No(Yes):

    def no(self):
        if Yes.a==1:
            print "No"
        else:
            print "Yes, but no"
        Yes.a-=1 #Note this line

Yes().yes()
No().no()
Yes().yes()
No().no()

Ответ на этот вопрос таков:

Yes().yes()
No().no()
Yes().yes()
No().no()

Надеюсь, этот пример поможет понять ваши знания о переменных класса. Дайте мне знать, если у вас есть какие-либо сомнения. :)

...