2014-07-24 43 views
2

是的,我是一個新的蟒蛇。這是我研究後的第一個程序。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++中的「靜態」類成員。

在python中,我們不需要在使用之前聲明一個成員。

這樣的代碼去:乳寧當

class MyHTMLParser(HTMLParser.HTMLParser): 
    def handle_starttag(self, tag, attrs): 
     if something: 
      self.urlList.append(target) 

但蟒蛇彈出某些錯誤,說MyHTMLParser有「urlList」無屬性。

我很困惑,爲什麼python不會自動添加它?

,所以我說了這樣的「初始化」(在我心中「的聲明」):

class MyHTMLParser(HTMLParser.HTMLParser): 
    def __init__(self): 
     self.urllist = [] 
    def handle_starttag(self, tag, attrs): 
     if something: 
      self.urlList.append(target) 

但在這種形式下,蟒蛇跟我談HTMLParser的一些錯誤,我發現這是因爲我沒有打電話給父母init()。

這樣的代碼去:

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父類INIT,我發現下面列出的兩種方法。

一個是愚蠢的,我去了HTMLParser的lib和發現它在初始化沒有()和複製:

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

HTMLParser.HTMLParser.__init__(self) 

我知道這是可行的,但很醜,所以我的問題是:

1,優先的方式來重寫它時調用父init()方法。

2,如何添加一個沒有「聲明」的列表成員就像我在代碼中列出的。

回答

1

要調用父類方法,您只需使用super(<currentClass>, self).method(<parent method arguments>)。在你的情況下,它會是這樣

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) 

參考super manual

正如「宣言」的 - 看起來你misundestood什麼「宣言」在python指。當你嘗試讀取的東西時,Python不會自動創建東西。所以,通過做

self.my_urllist = [] 

你只需告訴它創建一個空列表並將其存儲在my_urllist類成員。這不是「聲明」,而僅僅是一種安慰。然而,

self.my_urllist.append(target) 

讀作「請閱讀self.my_urllist不是試圖調用append方法上無論你讀過」。這裏有兩件事可能出錯:(1)self.my_urllist不存在; (2)self.my_urllist沒有append方法。

所以,爲了使它工作,你必須確保在你做之前self.my_urllist.append你實際上有self.my_urllist成員,它是一個列表。 Pythonic的做法是在__init__中創建my_urllist併爲其指定一些合理的值(在您的案例中爲空列表)。

如果你絕對不希望重寫__init__你可以被稱爲*懶初始化技術走」,像這樣:

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

property是一個裝飾,使方法看起來就像屬性但無論如何,創建一些對象屬性(_my_urllist)和初始化,它只是推遲,直到你真正需要它。

+0

「巨​​蟒當您嘗試讀的東西不會自動創建的東西。 「這非常有幫助,謝謝。 – Ethansong

+0

事實上,我試圖使用超級(MyHTMLParser,self).__ init __(),但結果是一個錯誤」TypeError:必須是類型,而不是classobj「 – Ethansong

+0

@Ethansong肯定與此有關http://stackoverflow.com/questions/9698614/super-raises-typeerror-must-be-type-not-classobj-for-new-style-class – J0HN

0

你的第二種方法是正確的做法。它不難看。

作爲替代,你可以這樣做:

super(MyHTMLParser, self).__init__() 

你正在做的一切正確的方式。

+0

非常感謝你。 – Ethansong

0

千萬不要複製父方法的代碼。這兩個標準選項調用父的__init__

HTMLParser.HTMLParser.__init__(self) 

super(MyHTMLParser, self).__init__() 

如果你使用Python 3,第二個選項已經被簡化爲

super().__init__() 

有沒有辦法以避免步驟self.my_urllist = []。畢竟,Python需要的一些的方式來說明這個屬性應該是一個列表。

+0

非常感謝你。 – Ethansong