0

私はもともと 1 つの長い関数として残していたスクリプトを持っています。

#! /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メソッドを呼び出す方法を見つけようとしています。

これは間違った方法ですか?これらのメソッドを 1 つの大きなメソッドとして残しておく必要がありますか?

4

5 に答える 5

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が辞書を使用してself.word_database()をinit関数に追加するたびにword_databaseが呼び出されるようにします__init__(self, word)。これにより、これらの機能を常に利用できるようになります。

第3に、オブジェクトをスクリプトとして扱い、Vocab()。dictionary(word)を実行する場合は、クラス構造を使用しない方がよいでしょう。Vocab()を使用して作業の一部を計算してから、他の作業を段階的に実行する(辞書を繰り返し呼び出す)ことを計画している場合は、クラス構造を維持します。しかし、現在それを使用している方法は、関数呼び出しのようなものです。(関数呼び出しのセマンティクスを保持する場合は、少なくとも元の関数をより小さな部分に分割する必要があります)。

于 2012-08-14T23:44:16.157 に答える
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 に答える
0

オブジェクト指向に移行せずに、最初にリファクタリングすることをお勧めします。クラスを作っても何も得られません。2 つのメソッドを定義するだけで、最後に次のようになります。

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