在下面的脚本中,创建了一个简单的web服务器,其中有一个类应该将GET
数据发送到sqlite3数据库。在
import SimpleHTTPServer
import SocketServer
import sqlite3
PORT = 8000
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
class DBLoggingHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super(DBLoggingHandler, self).__init__(*args, **kwargs)
self.db = sqlite3.connect('/home/cron1admin/crazysean/crazysean.db')
def do_GET(self):
self.db.execute("INSERT INTO crazysean (command, vers, path) VALUES (?, ?, ?)",
(self.command, self.request_version, self.path))
self.db.commit()
return super(DBLoggingHandler, self).do_GET()
DBLoggingHandler()
脚本的web服务器部分正常工作。我在终端输出中看到GET
数据。但是,我在db中创建的crazysean表中没有写入任何内容。你觉得我的剧本有什么问题吗?还是可能是别的什么问题?在
代码已经被更改以反映我所做的更改,但它仍然没有写入数据库。在
更新代码:
^{pr2}$
您缺少最后的咒语^{} :)
你又犯了一个错误,这个错误更大。实际上,您并不是在调用代码,而是在调用
SimpleHTTPRequestHandler
。在完整示例:
^{pr2}$首先你要这样做:
然后创建处理程序类并实例化它。在
所以,你的代码在“永远”之后才起作用。等它太久了。在
您要做的是将处理程序子类传递给服务器,而不是基类。如果你有这个:
^{pr2}$…而是这样做:
(或者去掉多余的一行并做
httpd = SocketServer.TCPServer(("", PORT), DBLoggingHandler
)您还必须将类的定义移到文件的顶部。在
但还有另一个问题。在
Python过去有两种不同的类:new-style and classic。他们几年前在3.0中修复了这个问题,但你仍然使用2。在
通常,您可以一直使用新样式的类,而不必担心旧类,但是偶尔您会遇到stdlib或第三方库中仍然使用旧方法的类,并且您希望从中继承。这就是这里发生的事。所以现在,可悲的是,你必须学习旧式课程。在
旧样式类不能做的事情是
super
。解决方法是显式调用基类的unbound方法。所以,与其这样:…你需要这个:
对于另一个
super
调用也是如此。在您知道发生这种情况的方式(不是通过查看基类)是当您收到关于}的错误消息时。这两种类型总是意味着某个地方涉及到一个经典类。在
classobj
或{等等,还有更多。在
不管白痴叫你把
self.db = …
的东西放到__init__
方法中,都是白痴。:)SocketServer
处理程序是一种奇怪的类。每个新请求构造一个新实例,__init__
方法调用handle
,直到销毁整个实例时才会返回。因此,在调用基类之后放入__init__
中的任何内容都不会发生,直到为时已晚。在这里要做的最简单的事情可能是使
db
成为一个全局变量。在其他条件相同的情况下,全球化是不好的。但在这种情况下,替代方案似乎要么覆盖来自三个不同类的功能,要么将其嵌入服务器实例并依赖于未记录的细节来访问它。在另外,您可能想关闭某个地方的数据库。在不关闭数据库的情况下终止程序不应该使其损坏,但如果计时错误,则可能意味着丢失最后一个事务。在
由于
serve_forever
永远不会返回,除非您按ctrl-c,所以不能将它放在该行之后;您需要一个with
语句(或finally
,或except BaseException
,或atexit
)。我不认为sqlite3.Connection
对象在Python的更高版本之前不会成为上下文管理器,因此您必须使用closing
上下文管理器。在所以:
请看下面的示例:
https://docs.python.org/2/library/sqlite3.html
您需要创建一个游标,通过游标执行语句,然后提交连接。在
相关问题 更多 >
编程相关推荐