2012-08-14 100 views
0

我有一個腳本,我最初留作一個長功能。使用Python類的方法

#! /usr/bin/env python 
import mechanize 
from BeautifulSoup import BeautifulSoup 
import sys 
import sqlite3 

def dictionary(word): 
    br = mechanize.Browser() 
    response = br.open('http://www.dictionary.reference.com') 
    br.select_form(nr=0) 
    br.form['q'] = word 
    br.submit() 
    definition = BeautifulSoup(br.response().read()) 
    trans = definition.findAll('td',{'class':'td3n2'}) 
    fin = [i.text for i in trans] 
    query = {} 
    word_count = 1 
    def_count = 1 
    for i in fin: 
     query[fin.index(i)] = i 
    con = sqlite3.connect('/home/oberon/vocab_database/vocab.db') 
    with con: 
     spot = con.cursor() 
     spot.execute("SELECT * FROM Words") 
     rows = spot.fetchall() 
     for row in rows: 
      word_count += 1 
     spot.execute("INSERT INTO Words VALUES(?,?)", (word_count,word)) 
     spot.execute("SELECT * FROM Definitions") 
     rows = spot.fetchall() 
     for row in rows: 
      def_count += 1 
     for q in query: 
      spot.execute("INSERT INTO Definitions VALUES(?,?,?)", (def_count,query[q],word_count)) 
      def_count += 1 
    return query 

print dictionary(sys.argv[1]) 

現在,我想通過創建一個類來練習OOP表單。我認爲最好將此分解成至少兩個函數。

我想出了:

#! /usr/bin/env python 
import mechanize 
from BeautifulSoup import BeautifulSoup 
import sys 
import sqlite3 


class Vocab: 
    def __init__(self): 
     self.word_count = 1 
     self.word = sys.argv[1] 
     self.def_count = 1 
     self.query = {} 

    def dictionary(self,word): 
     self.br = mechanize.Browser() 
     self.response = self.br.open('http://www.dictionary.reference.com') 
     self.br.select_form(nr=0) 
     self.br.form['q'] = word 
     self.br.submit() 
     self.definition = BeautifulSoup(self.br.response().read()) 
     self.trans = self.definition.findAll('td',{'class':'td3n2'}) 
     self.fin = [i.text for i in self.trans] 
     for i in self.fin: 
      self.query[self.fin.index(i)] = i 
     return self.query 

    def word_database(self): 
     self.con = sqlite3.connect('/home/oberon/vocab_database/vocab.db') 
     with self.con: 
      self.spot = self.con.cursor() 
      self.spot.execute("SELECT * FROM Words") 
      self.rows = self.spot.fetchall() 
      for row in self.rows: 
       self.word_count += 1 
      self.spot.execute("INSERT INTO Words VALUES(?,?)", (self.word_count,self.word)) 
      self.spot.execute("SELECT * FROM Definitions") 
      self.rows = self.spot.fetchall() 
      for row in self.rows: 
       self.def_count += 1 
      for q in self.query: 
       self.spot.execute("INSERT INTO Definitions VALUES(?,?,?)", (self.def_count,self.query[q],self.word_count)) 
       self.def_count += 1 



Vocab().dictionary(sys.argv[1]) 

我知道,在最後一行時,我打電話翻譯()詞典(sys.argv中[1])這隻會運行詞典方法。我試圖找出如何在每次運行腳本時調用word_database方法。

這是錯誤的方式去做這件事嗎?我是否應該將這些方法僅僅作爲一種大型方法?

+1

只是打電話給你的方法word_database在通過另一種方法 – 2012-08-14 23:49:50

回答

1

它看起來不錯,作爲一個腳本給我。唯一真正的問題是,爲什麼你做

for row in rows: 
     word_count += 1 

,而不是

word_count += len(rows) 

至於你的問題,你叫邊做邊

self.word_database() 
+0

在第一部分,這第一次我在sqlite3的工作到一個腳本,它花了我每分鐘運行一次,就會想到如何讓這個詞成爲'id'。你完全正確,謝謝:)!第二部分,你說的只是將其添加到字典方法? – tijko 2012-08-14 23:43:38

1

word_database我真的不知道有什麼它是一個類的優點,但如果你想調用一個實例的多個方法,你將需要爲實例指定一個名稱。

vocab = Vocab() 
vocab.dictionary(...) 
vocab.word_database(...) 
+0

我在想這裏沒有太多的優勢,沒有太多的代碼可以用。我真的想要練習'形式'。 – tijko 2012-08-14 23:48:58

1

你只需要在原始腳本中的相同點調用word_database。

def dictionary(self,word): 
    self.br = mechanize.Browser() 
    self.response = self.br.open('http://www.dictionary.reference.com') 
    self.br.select_form(nr=0) 
    self.br.form['q'] = word 
    self.br.submit() 
    self.definition = BeautifulSoup(self.br.response().read()) 
    self.trans = self.definition.findAll('td',{'class':'td3n2'}) 
    self.fin = [i.text for i in self.trans] 
    for i in self.fin: 
     self.query[self.fin.index(i)] = i 

    # Continue the script... 
    self.word_database() 

    return self.query 
+0

非常感謝和迴應! – tijko 2012-08-14 23:49:58

1

幾件事情:

首先,你不需要做所有的變量self.var_name只是因爲你包裹在其中的一類。如果函數調用完成後不需要該變量,則只需使用局部變量。

其次,爲了讓word_database在每次Vocab使用字典時添加self.word_database()到您的初始函數__init__(self, word)。這將確保這些功能始終可用。第三,如果你只是想把對象當作一個腳本來使用並且使用Vocab()。dictionary(單詞),那麼你最好不要使用類結構。如果你計劃用Vocab()計算一些工作,然後逐步做其他工作(重複調用字典),那麼保持類結構。但是你目前使用它的方式就像是一個函數調用。 (如果你保留函數調用語義,你至少應該把原始函數分成更小的部分)。

+0

因爲這個原因,我正在考慮在我的原始問題中添加幾個單獨的問題。特別是如何清理代碼並使用最佳/更好的形式。再次感謝,非常有幫助。 – tijko 2012-08-14 23:53:06

0

我建議先不重構面向對象的重構。通過上課,你不會獲益。只是定義了兩種方法,並在最後:

dictionary(sys.argv[1) 
word_database() 
+0

我知道這不是一個理想的情況,使它成爲面向對象的代碼,只是想實踐一些。不過謝謝你的回答。 – tijko 2012-08-14 23:56:01