Python 创建装饰类?

Python 创建装饰类?,python,class,decorator,Python,Class,Decorator,我一直在阅读和学习修饰符及其在python中的使用。我想我会尝试为我一直在编写的python脚本创建一个装饰器。从我所读到的内容来看,我知道应该有很多方法可以使用我所拥有的特定代码来实现这一点 到目前为止: #! /usr/bin/env python import mechanize from BeautifulSoup import BeautifulSoup import sys import sqlite3 ## create the Decorator class ## class

我一直在阅读和学习修饰符及其在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
打印、运行并执行decorator方法中的所有操作,但是,
Vocab().dictionary()
打印出
None

You have 2 tables 
You have 4 entries
None

我确信这里的错误不仅仅是运行
Vocab().dictionary()
方法。如果有人能帮我弄清楚是什么阻碍了它的正常工作,那就太好了,我应该和装饰师一起研究其他的事情,甚至更好

self.func
没有调用函数,正如您所期望的那样(从注释判断)。要调用它,您需要执行
self.func()
。此外,如果希望包装函数以便将值返回到外部,则需要执行
return self.func()
,或者存储值并稍后返回(在使用
块的
之后)

然而,您的代码在其他方面似乎有点可疑。例如,您有
\uuuu call\uuuu
接受
func
作为参数,但它没有被使用,而装饰程序假定包装的
dictionary
方法接受名为
word
的参数,该参数显然应该是字符串。这让我觉得你误解了装饰师的工作原理


当您使用
@Deco
作为装饰器时,类将作为参数传递要装饰的函数。
Deco
实例本身就是结果,因此在此之后,
Vocab.dictionary
Deco
的一个实例。然后,当您调用
Vocab().dictionary()
时,您正在调用
Deco
调用方法。因此,如果您试图包装
字典
,您的Deco的
\uuu调用
应该接受与
字典
接受的参数相同的参数,并且应该将它们传递到
字典
。(这可能是您调用
self.func()
时出错的原因。您调用的
dictionary
没有参数,但它需要一个参数。)

self.func
没有像您预期的那样调用函数(从注释判断)。要调用它,您需要执行
self.func()
。此外,如果希望包装函数以便将值返回到外部,则需要执行
return self.func()
,或者存储值并稍后返回(在使用
块的
之后)

然而,您的代码在其他方面似乎有点可疑。例如,您有
\uuuu call\uuuu
接受
func
作为参数,但它没有被使用,而装饰程序假定包装的
dictionary
方法接受名为
word
的参数,该参数显然应该是字符串。这让我觉得你误解了装饰师的工作原理


当您使用
@Deco
作为装饰器时,类将作为参数传递要装饰的函数。
Deco
实例本身就是结果,因此在此之后,
Vocab.dictionary
Deco
的一个实例。然后,当您调用
Vocab().dictionary()
时,您正在调用
Deco
调用方法。因此,如果您试图包装
字典
,您的Deco的
\uuu调用
应该接受与
字典
接受的参数相同的参数,并且应该将它们传递到
字典
。(这可能是您在调用
self.func()
时出错的原因,您调用的
dictionary
没有参数,但它需要一个参数。)

查看您的代码,您似乎还没有明确定义装饰程序应该做什么。可能重复@RC我已经在我的收藏夹下标记了它。我想问几个问题来澄清那篇文章中的一些内容。看看你的代码,似乎你还没有明确定义装饰师应该做什么。可能是@RC的重复我已经在我的收藏夹下标记了它。我想问几个问题来澄清那篇文章中的一些内容。@tijko:看我编辑的答案。我想你误解了类的
\uuuuu init\uuuu
\uuu call\uuuuu
是如何/何时被调用的。我不认为这是尝试使用装饰器的最佳地方。我想用一个在某种程度上,我看到越来越多,这是不是这样做的地方。谢谢你的回复:)@tijko:看我编辑的答案。我想你误解了类的
\uuuuu init\uuuu
\uuu call\uuuuu
是如何/何时被调用的。我不认为这是尝试使用装饰器的最佳地方。我想用一个在某种程度上,我看到越来越多,这是不是这样做的地方。感谢您的回复:)