Python:如何在派生类中添加空列表
是的,我是python的新手。这是我学习后的第一个课程 这是一个HTML爬虫程序,用于获取某个站点上的所有mp3文件 我已经完成了这项工作,但有两个问题困扰着我,以下是我所经历的: 我试图添加一个派生自HTMLParser的类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
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)