Форум сайта python.su
скрипт на питоне2 прекрасно скачивает файл с фтп, сохраняет его в локальный файл и снова закачивает на сервер
но при запуске на питоне3 - вылазит эксепшен
# файл скачали в файл tmp, все отлично
# без изменений пробуем закачать:
file = open('tmp', 'rt')
ftp.storlines('STOR module1.php', file)
file.close()
File "/usr/local/lib/python3.2/ftplib.py", line 488, in storlines
if buf[-1] in B_CRLF: buf = buf[:-1]
TypeError: Type str doesn't support the buffer API
def storlines(self, cmd, fp, callback=None)
...
while 1:
buf = fp.readline()
if not buf: break
if buf[-2:] != B_CRLF:
if buf[-1] in B_CRLF: buf = buf[:-1]
buf = buf + B_CRLF
file = open('tmp', 'rt')
f = file.readline()
print(f[0:2])
Офлайн
от безысходности пока закачиваю через binary mode
и судя по этому сообщению - http://stackoverflow.com/questions/540342/python-3-0-urllib-parse-error-type-str-doesnt-support-the-buffer-api - если я его правильно понял, это баг питона
Офлайн
file = open('tmp', ‘rb’)
Офлайн
ну да, я так и делаю
но что это за баг? почему второй питон заливает текстовые файлы, а третий нет?
Офлайн
Не называйте ваши кривые руки багом.
В чем отличие между файлом, открытом в текстовом и бинарном режиме?
Чем отличаются str и bytes?
Что получится в результате ‘a’ + b'b' ?
Офлайн
багом назвал не я, а автор топика, на который я сослался
за 5 лет кодинга на пхп не припомню, чтобы я когда-нибудь мог вообще предположить, что причина ошибок не я, а интерпретатор
на ваши вопросы ответить толком не могу
заметил лишь то, что ‘a’ + b'b' в питон2 дает ‘ab’, а в питон3 - эксепшен
но почему - не понимаю
Офлайн
потому что разные типы: str и bytes. Их специально развели по разным углам и затруднили совместную работу.
str - это строка юникодных символов. bytes - просто байты. Или строка в какой-нибудь кодировке.
Именно потому, что кодировки бывают разные - преобразовывать нужно явно через .decode/.encode.
В python 2 такой проблемы нет. Зато есть более фундаментальная - посмотрите, сколько на этом форуме по кодировкам вопросов задают.
Файл, открытый в тексте будет читать str. Бинарный - bytes.
Фабрика open возвращает экземпляры разных классов.
Офлайн
тем не менее, это нисколько не приоткрывает завесу тайны - почему на фтп не закачивается текстовый файл, открытый как текст в текстовом режиме через storlines?
какое значение тут может иметь кодировка? в какой файл читается - в такой сервер и должен сохранять, разве нет?
Отредактировано (Фев. 2, 2011 07:05:39)
Офлайн
Именно потому, что ftp сервер не заботится о кодировке - так называемые текстовые файлы в ftp (storlines/retrlines) на самом деле работают как бинарные с одним единственным исключением - принимают конец строки в любом виде (LF, CR, CRLF). Во всех остальных аспектах это байты. Собственно говоря ftp ничего не говорит о тексте - есть lines mode и binary mode. lines mode заменяет концы строк так, чтобы они было CRLF. binary mode этого преобразования не делает.
Есть еще и то, как работает ftp server.
lines mode - TYPE A, ascii bytes. Т.е. спецификация явно запрещает пересылку не ascii текста (в то время как сервера обычно позволяют). Старайтесь не использовать этот режим до тех пор, пока не будете точно знать что вы делаете.
binary mode - TYPE I, image. Просто байты как есть, без всяких ограничений. Именно то, что нужно.
Еще есть несколько вариантов команды TYPE, совсем экзотических. Все они никому сейчас не нужны (как и TYPE A на самом деле).
Не уверен, понятно ли изложил но лучше у меня не получилось.
Офлайн