Python:如何在派生类中添加空列表

Python:如何在派生类中添加空列表,python,class,member,derived,Python,Class,Member,Derived,是的,我是python的新手。这是我学习后的第一个课程 这是一个HTML爬虫程序,用于获取某个站点上的所有mp3文件 我已经完成了这项工作,但有两个问题困扰着我,以下是我所经历的: 我试图添加一个派生自HTMLParser的类 class MyHTMLParser(HTMLParser.HTMLParser): def handle_starttag(self, tag, attrs): pass 成功了。所以我尝试添加一个列表成员来记住它遇到的每个URL class

是的,我是python的新手。这是我学习后的第一个课程

这是一个HTML爬虫程序,用于获取某个站点上的所有mp3文件

我已经完成了这项工作,但有两个问题困扰着我,以下是我所经历的:

我试图添加一个派生自HTMLParser的类

class MyHTMLParser(HTMLParser.HTMLParser):
    def handle_starttag(self, tag, attrs):
        pass
成功了。所以我尝试添加一个列表成员来记住它遇到的每个URL

class MyHTMLParser(HTMLParser.HTMLParser):
    urlList = []
    def handle_starttag(self, tag, attrs):
        pass
<>但是很快我发现它就像C++中的“static”类成员。

在python中,我们不需要在使用前声明成员

因此,代码转到:

class MyHTMLParser(HTMLParser.HTMLParser):
    def handle_starttag(self, tag, attrs):
        if something:
            self.urlList.append(target)
class MyHTMLParser(HTMLParser.HTMLParser):
    def __init__(self):
        #DO PARENT CLASS INIT
        self.urllist = []
    def handle_starttag(self, tag, attrs):
        if something:
            self.urlList.append(target)
但是python在运行它时出现了一些错误,说MyHTMLParser没有“urlList”属性

我很困惑,为什么python不会自动添加它

因此,我添加了如下“初始化”(以及我脑海中的“声明”):

class MyHTMLParser(HTMLParser.HTMLParser):
    def __init__(self):
        self.urllist = []
    def handle_starttag(self, tag, attrs):
        if something:
            self.urlList.append(target)
但是在这种形式下,python告诉我一些关于HTMLParser的错误,我发现这是因为我没有调用父init()

因此,代码转到:

class MyHTMLParser(HTMLParser.HTMLParser):
    def handle_starttag(self, tag, attrs):
        if something:
            self.urlList.append(target)
class MyHTMLParser(HTMLParser.HTMLParser):
    def __init__(self):
        #DO PARENT CLASS INIT
        self.urllist = []
    def handle_starttag(self, tag, attrs):
        if something:
            self.urlList.append(target)
在#DO PARENT类INIT中,我找到了下面列出的两种方法

一个是愚蠢的,我去了HTMLPasser库,发现它在init()中做了什么,并复制了:

self.reset() #it's what HTMLParser did in __init__()

我知道这是可行的,但很难看,所以我的问题是:

1,重写父init()方法时调用它的优雅方式


2、如何添加列表成员而不需要代码中列出的“声明”。

第二种方法是正确的。这并不难看

作为替代方案,您可以执行以下操作:

super(MyHTMLParser, self).__init__()

您正在以正确的方式执行所有操作。

切勿复制父方法的代码。调用父级的
\uuuuu init\uuuu
的两个标准选项是

HTMLParser.HTMLParser.__init__(self)

如果您使用的是Python3,那么第二个选项已简化为

super().__init__()

无法避免self.my_urlist=[]步骤。毕竟,Python需要某种方法来判断这个属性应该是一个列表。

要调用父类方法,只需使用
super(,self).method()
。在你的情况下,可能是这样的

class MyHTMLParser(HTMLParser.HTMLParser):
    def __init__(self):
        #python 3
        super(MyHTMLParser, self).__init()
        # in python 2 HTMLParser is an old-style class, so the above won't work
        HTMLParser.HTMLParser.__init__(self)


至于“声明”——看起来您误解了“声明”在python中的含义。当您尝试读取某些内容时,Python不会自动创建内容。因此,通过这样做

self.my_urllist = []
您只需告诉它创建一个空列表,并将其存储在
myurlist
类成员处。这不是“宣言”,只是一项判决。但是,

self.my_urllist.append(target)
读作“请阅读
self.my_urlist
,然后尝试对所读内容调用
append
方法”。这里有两件事可能出错:(1)我的清单不存在;(2)
self.my_urlist
没有
append
方法

因此,为了使其工作,您必须确保在执行
self.my_urlist.append
之前,您实际上拥有
self.my_urlist
成员,并且它是一个列表。python的方法是在
\uuuu init\uuuu
中创建
my\u urlist
,并为其分配一些合理的值(在您的情况下为空列表)

如果您绝对不想覆盖
\uuuuu init\uuuu
,您可以使用称为“惰性初始化”的技术,如下所示:

class MyHTMLParser(HTMLParser.HTMLParser):
    @property
    def my_urllist(self):
        if not hasattr(self, '_my_urllist'):
             self._my_urllist = []
        return self._my_urllist

是一个使方法看起来像属性的装饰器。但无论如何,某些对象属性(
\u my\u urlist
)是创建和初始化的,它只是延迟到您真正需要它为止。

“当您尝试读取某些内容时,Python不会自动创建内容。“这非常有帮助,谢谢。事实上,我曾尝试使用super(MyHTMLParser,self)。\uuuu init\uuuu()但结果是一个错误“TypeError:must-be-type,not-classobj”@ethang肯定与Python 2.7.8相关(默认,2014年6月30日,16:08:48)