Python 创建装饰类?
我一直在阅读和学习修饰符及其在python中的使用。我想我会尝试为我一直在编写的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
#! /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
是如何/何时被调用的。我不认为这是尝试使用装饰器的最佳地方。我想用一个在某种程度上,我看到越来越多,这是不是这样做的地方。感谢您的回复:)