0

...但它并没有以同样的方式逃脱它两次。

我正在尝试将 ASCII 输出从 gpg 上传到网站。所以,到目前为止,我得到的只是查询表,向我显示它获得的数据,然后在它为 HTTP POST 请求编码后将其显示给我:

cnx = connect()
sql = ("SELECT Data FROM SomeTable")
cursor = cnx.cursor()
cursor.execute(sql)
for (data) in cursor:
        print "encoding : %s" % data
        postdata = urllib.urlencode( { "payload" : data } ) 
        print "encoded as %s" % postdata

...但我得到的是:

encoding : -----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.12 (GNU/Linux)
.... etc...

encoded as payload=%28u%27-----BEGIN+PGP+MESSAGE-----%5CnVersion%3A+GnuPG+v1.4.12+... etc ...

需要注意的部分是换行符并没有像我预期的那样变成 %0A。相反,它们以某种方式转义为“\n”,然后反斜杠转义为 %5C,因此换行符变为“%5Cn”。更奇怪的是,数据前面加上了%28u%27,结果是“ (u' ”。

奇怪的是,如果我只是做一个基本的测试:

data = "1\n2"
print data
print urllib.urlencode( { "payload" : data } )

我得到了我的期望,换行符变成 %0A ...

1
2
payload=1%0A2

所以,我的预感是,从 mysql 查询返回的数据元素与我的文字“1\n2”(可能是一个 1 元素字典...不知道)不是同一种字符串,但我没有Python功夫知道如何检查它。

有谁知道这里发生了什么,以及我该如何解决?如果没有,关于如何通过 HTTP 发布此内容并正确转义所有内容的任何建议?

4

1 回答 1

0

假设connect()是来自某些DB-API 2.0兼容数据库接口(如内置sqlite3或最流行的mysql接口)的函数,for (data) in cursor:是迭代Row对象,而不是字符串。

当您打印出来时,您实际上是在打印str(data)(通过将其传递给%s格式)。如果你想编码相同的东西,你必须编码str(data).

但是,更好的方法是首先将行作为(一列的)行来处理,而不是依赖于str做你想做的事。

PS,如果您试图依靠元组解包来制作data每一行的第一个元素,那么您做错了:

for (data) in cursor:

… 等同于:

for data in cursor:

如果你想要一个元素tuple,你需要一个逗号:

for data, in cursor:

(如果需要,您也可以添加括号,但它们仍然没有任何区别。)

具体来说,迭代游标将调用可选__iter__方法,该方法返回游标本身,然后循环调用其next上的方法,这与调用相同,fetchone()直到结果集耗尽,并fetchone记录为返回“单个序列”,其类型未定义。在大多数实现中,这是一种特殊的行类型,例如sqlite3.Row,可以像访问一样访问它,tuple但对于以表格格式打印、允许按名称访问等具有特殊语义。

于 2013-02-26T20:16:36.637 回答