0

我有一个最初作为一个长函数留下的脚本。

#! /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])

我知道在我调用Vocab().dictionary(sys.argv[1])的最后一行时,这只会运行字典方法。我试图弄清楚每次我仍然运行脚本时如何调用word_database方法。

这是错误的方法吗?我应该把这些方法作为一种大方法吗?

4

5 回答 5

1

在我看来,它作为一个脚本很好。唯一真正的问题是你为什么这样做

for row in rows:
        word_count += 1

代替

word_count += len(rows)

至于你的问题,你打电话给 word_database 做

self.word_database()
于 2012-08-14T23:39:06.133 回答
1

我不确定它作为一个类有什么好处,但是如果你想调用一个实例的多个方法,你需要为实例分配一个名称。

vocab = Vocab()
vocab.dictionary(...)
vocab.word_database(...)
于 2012-08-14T23:41:19.797 回答
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
于 2012-08-14T23:42:04.253 回答
1

有几件事:

首先,您不需要将所有变量都设为 self.var_name ,因为您将它们包装在一个类中。如果函数调用完成后不需要该变量,只需使用局部变量即可。

其次,每次 Vocab 使用字典时都会调用 word_database,将 self.word_database() 添加到您的 init 函数__init__(self, word)中。这将确保这些功能始终可用。

第三,如果您只是要将对象视为脚本并执行 Vocab().dictionary(word),则最好不要使用类结构。如果您打算使用 Vocab() 计算一些工作,然后增量地做其他工作(重复调用字典),那么保持类结构。但是你目前使用它的方式就像一个函数调用。(如果您保留函数调用语义,您至少应该将原始函数分解为更小的部分)。

于 2012-08-14T23:44:16.157 回答
0

我建议首先重构而不是面向对象。上课不会有任何收获。只需定义您的两种方法,最后:

dictionary(sys.argv[1)
word_database()
于 2012-08-14T23:46:44.910 回答