【问题标题】:Class variable refuses to work via "self" but works with class name (Python)类变量拒绝通过“self”工作,但使用类名(Python)
【发布时间】:2020-02-29 12:08:49
【问题描述】:

我在这个类中有一个简单的类和一个类变量:

class QuotesToScrape:

    authors_list = []

    def __init__:

这个类里面的一个方法里面有一行代码(方法是从init调用的):

def gather_authors_list(self):
    self.authors_list = some_value

此行不起作用,变量 authors_list 仍为空。但是,如果我将“self”更改为类名,它就可以正常工作:

def gather_authors_list(self):
    QuotesToScrape.authors_list = some_value

没有使用装饰器。我觉得这是我需要了解的一些重要技巧,以防止我将来出现严重问题。

稍后添加。重要部分:我有另一个类变量“quotes”,它工作得很好。这是我的代码的几乎完整片段。类变量“quotes”可以,类变量“authors_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])

稍后添加。问题解决了。更改了最后一行以匹配来自 cmets 的方向。这解决了我的问题,now 方法不会创建新变量,而是使用现有的空类变量:

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

【问题讨论】:

    标签: python-3.x class class-variables


    【解决方案1】:

    在有问题的版本后编辑:当您说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()
    

    我希望通过这个例子可以帮助你理解类变量的知识。如果您有任何疑问,请告诉我。 :)

    【讨论】:

    • 从技术上讲,我调用了从 init 更改 author_list 变量的方法。
    • 谢谢。现在我的问题解决了,一切正常。
    • 很高兴,您发现它很有帮助。 :)
    【解决方案2】:

    问题在于您的代码创建了两个变量:

    类的命名空间中的一个

    class QuotesToScrape:
    
        authors_list = []
    

    另一个在对象的命名空间中。

    def gather_authors_list(self):
        self.authors_list = some_value
    

    变量是通过python中的赋值来定义的。因此,您分配它们的位置很重要。

    请注意,从对象实例中,通过self,您仍然可以到达类变量:如果在对象的命名空间中找不到,则在类的命名空间(和超类)中查找该名称

    【讨论】:

    • 我添加了代码的扩展片段:在类的开头定义的另一个变量运行良好。
    • 请再次阅读我的回答。请在一本合适的书上更深入地研究python。当然,quotes 变量是有效的:它不是通过 self 分配给另一个变量!它是通过 self 到达的,它的append 方法被调用。我放弃了
    • 还是谢谢你。我看到问题并看到解决方案,我的代码现在完美运行。我希望有一天我也能理解为什么方法会在“self.x =”和“self.x.append”之间产生如此大的差异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 2023-03-17
    • 2010-09-18
    • 1970-01-01
    • 2018-08-31
    • 2018-08-26
    相关资源
    最近更新 更多