5

Python3 で記述された単純な Web サーバー ( のクラスを使用http.server) があり、2 から 3 に移植しています。

次のコードがあります。

# More code here...
postvars = cgi.parse_qs(self.rfile.read(length),
                        keep_blank_values=1)
something.json_run(json.dumps(postvars))

スローするもの:

TypeError: keys must be a string

parse_qsデータを調べることで、キーをバイトとしてエンコードしているように見えると判断しました。これがエラーをスローしているものです(json明らかにバイトが好きではありません)。

import json
json.dumps({b'Throws error' : [b"Keys must be a string"]})
json.dumps({'Also throws error': [b'TypeError, is not JSON serializable']})
json.dumps({'This works': ['No bytes!']})

ここでの最善の解決策は何ですか? Python 2 では、 の代わりに をparse_qs使用するため、コードは正常に機能します。私の最初の考えは、おそらく JSON シリアライザーを作成する必要があるということです。それほど単純なことは難しいというわけではありませんが、別の方法でできるのであれば、そうしたくないと思います (たとえば、辞書をバイトの代わりに文字列を使用するように変換します)。strbytes

4

1 に答える 1

2

まず、このcgi.parse_qs関数は推奨されておらず、単に のエイリアスであるためurllib.parse.parse_qs、インポート パスを調整する必要がある場合があります。

次に、バイト文字列を parse メソッドに渡します。代わりに通常の (Unicode) 文字列を渡すと、parse_qsメソッドは通常の文字列を返します。

>>> from urllib.parse import parse_qs
>>> parse_qs(b'a_byte_string=foobar')
{b'a_byte_string': [b'foobar']}
>>> parse_qs('a_unicode_string=foobar')
{'a_unicode_string': ['foobar']}

そのため、最初にファイル読み取りバイト文字列を通常の文字列にデコードする必要があります。

于 2012-06-11T17:14:34.690 に答える