0

私はデコレータとそれらのPythonでの使用について読んで学んでいます。私が取り組んできたPythonスクリプトのデコレータを作成しようと思いました。私が読んだことから、私が持っている特定のコードでこれを行う方法はたくさんあるはずです。

ここのところ:

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

## create the Decorator class ##

class Deco:
## initialize function and pass in the function as an argument ##
    def __init__(self,func):
        self.func = func
## use the built in __call__ method to run when the decorator is called ##
## I having issues knowing what the proper to pass the function in as an argument ##
    def __call__(self,func):
## right here I going to call the Vocab().dictionary() method ##
        self.func
## I can have the Vocab method run after I don't have a preference ##
## this decorator is going to find the number of tables and entries in the ##
## database with every call ##
        conn = sqlite3.connect('/home/User/vocab_database/vocab.db')
        with conn:
            cur = conn.cursor()
            cur.execute("SELECT name FROM sqlite_master WHERE type='table'")
            total = cur.fetchall()
            print "You have %d tables " % len(total)
            cur.execute("SELECT * FROM %s" % (total[0][0],))
            ent = cur.fetchall()
            print "You have %d entries" % len(ent)

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

    @Deco        
    def dictionary(self,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]
        for i in fin: 
            self.query[fin.index(i)] = i
        self.create_database()
        self.word_database()
        return self.query

    def create_database(self):
        con = sqlite3.connect('/home/oberon/vocab_database/vocab.db')
        with con:
            cur = con.cursor()
            cur.execute("CREATE TABLE IF NOT EXISTS Words(vocab_id INTEGER PRIMARY KEY, vocab TEXT)")
            cur.execute("CREATE TABLE IF NOT EXISTS Definitions(def_id INTEGER, def  TEXT, def_word INTEGER, FOREIGN KEY(def_word) REFERENCES Words(vocab_id))")

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

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

このコードを実行するDecoと、デコレータのメソッド内ですべてが出力、実行、実行されますが、次のようにVocab().dictionary()出力されNoneます。

You have 2 tables 
You have 4 entries
None

Vocab().dictionary()メソッドを実行するだけでなく、もっと間違っていると確信しています。誰かがこれが適切に機能するのを妨げているものに光を当てるのを手伝うことができれば、それは素晴らしいことです.

4

1 に答える 1

3

self.funcあなたが期待しているように(コメントから判断すると)、関数を呼び出しません。それを呼び出すには、する必要がありますself.func()。さらに、値が外部に返されるように関数をラップする場合は、 を実行するreturn self.func()か、値を保存して後で (withブロックの後) 返す必要があります。

ただし、コードは他の点で少し疑わしいようです。たとえば、引数として__call__受け入れていますが、それは使用されていませんが、デコレーターがラップすると思われるメソッドは、明らかに文字列であると思われる引数を受け入れます。これは、デコレータの仕組みを誤解していると思います。funcdictionaryword

デコレータとして使用する場合@Deco、クラスにはデコレートする関数が引数として渡されます。Decoインスタンス自体が結果なので、この後はのVocab.dictionaryインスタンスですDeco。次に を呼び出すと、 のメソッドVocab().dictionary()が呼び出されます。したがって、 をラップしようとしている場合、Decoは受け入れるのと同じ引数を受け入れる必要があり、それらを に渡す必要があります。(これが --- でエラーが発生した理由かもしれませんが、引数なしで呼び出していましたが、引数が必要です。)__call__Decodictionary__call__dictionarydictionaryself.func()dictionary

于 2012-08-20T05:16:02.593 に答える