2009-02-12 3 views
23
File "/usr/local/lib/python3.0/cgi.py", line 477, in __init__ 
    self.read_urlencoded() 
    File "/usr/local/lib/python3.0/cgi.py", line 577, in read_urlencoded 
    self.strict_parsing): 
    File "/usr/local/lib/python3.0/urllib/parse.py", line 377, in parse_qsl 
    pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] 
TypeError: Type str doesn't support the buffer API 

Может ли кто-нибудь направить меня на то, как этого избежать? Я получаю это через подачу данных в cgi.Fieldstorage, и я не могу сделать это иначе.Ошибка Python 3.0 urllib.parse «Тип str не поддерживает API-интерфейс буфера»

ответ

28

URLLIB пытается сделать:

b'a,b'.split(',') 

Который не работает. байтовые строки и строки Юникода смешиваются еще менее плавно в Py3k, чем они привыкли, - сознательно, чтобы проблемы с кодировкой шли неправильно раньше, чем позже.

Таким образом, ошибка довольно непрозрачно говорит вам, что вы не можете передать строку байта в urllib.parse. Предположительно, вы делаете запрос POST, где строка, закодированная в форме, входит в cgi как тело контента; тело содержимого по-прежнему является байтовой строкой/потоком, так что теперь он сталкивается с новым urllib.

Так что, это ошибка в cgi.py, еще одна жертва преобразования 2to3, которая не исправлена ​​должным образом для новой модели строк. Он должен преобразовывать входящий поток байтов в символы перед передачей их в urllib.

Я упоминал библиотеки Python 3.0 (особенно связанные с веб-сайтами), все еще довольно шонки? :-)

+0

Да. До сих пор я заметил огромные проблемы с cgi, urllib и wsgiref. Надеюсь, они скоро исправятся. :( –

+0

Действительно. Импульс в WEB-SIG, похоже, остановился, никто, похоже, не хочет владеть этим вопросом. Очень разочаровывает. – bobince

+0

Я считаю, что это должно, наконец, правильно работать в 3.2 (см. Http: // bugs .python.org/issue4953). – ncoghlan

13

Из учебника python (http://www.python.org/doc/3.0/tutorial/stdlib.html) приведен пример использования метода urlopen. Это вызывает ту же ошибку.

for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): 
    if 'EST' in line or 'EDT' in line: # look for Eastern Time 
     print(line) 

Вам нужно будет использовать функцию str для преобразования байта thingo в строку с правильной кодировкой. Как указано ниже:

for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): 
    lineStr = str(line, encoding='utf8') 
    if 'EST' in lineStr or 'EDT' in lineStr: # look for Eastern Time 
     print(lineStr) 
+3

Было бы действительно интересно предоставить решение, которое работает с обеими версиями python. – sorin

 Смежные вопросы

  • Нет связанных вопросов^_^