2012-01-03 2 views
1

Я создаю скрипт для преобразования большого количества данных в формат CSV. Он работает в Google AppEngine, используя API-интерфейс mapreduce, который имеет значение только в том смысле, что он означает, что каждая строка данных отформатирована и выводится отдельно, в функции обратного вызова.Форматирование одной строки как CSV

Я хочу воспользоваться логикой, которая уже существует в модуле csv, чтобы преобразовать мои данные в правильный формат, но поскольку CSV-писатель ожидает файл-подобный объект, мне нужно создать экземпляр StringIO для каждого строка, записать строку в объект, а затем вернуть содержимое объекта каждый раз.

Это кажется глупым, и мне интересно, есть ли способ получить доступ к внутренней логике форматирования CSV модуля csv без письменной части.

+0

Помогает ли модуль 'tempfile'? Вы можете дать дескриптор файла, который на самом деле не отображается в ОС. – wim

+0

@wim Спасибо, но на самом деле. Мне все равно нужен отдельный для каждой строки, даже если бы не тот факт, что нет доступа к файловой системе AppEngine. –

+0

Никогда не смотрел на mapreduce, поэтому я не уверен в ограничениях, в частности, когда речь идет о среде выполнения обратного вызова. Выполняется ли ваша программа (которая обеспечивает обратный вызов) во время всего вызова mapreduce? То есть. можете ли вы сохранить глобальное состояние, или вам действительно нужно каждый раз переустанавливать такие вещи, как 'StringIO'? (Не предлагая хранить глобальные объекты, заметьте, это просто я хотел бы знать окружающую среду) –

ответ

3

Модуль csv обертывает модуль _csv, который написан на C. Вы можете захватить источник для него и изменить его, чтобы не требовать файл-подобный объект, но, ковыряясь в модуле, я не вижу никаких ясный способ сделать это без перекомпиляции.

+0

(и здесь App Engine становится чрезвычайно актуальным, поскольку вы не можете развернуть повторно скомпилированные расширения C) – geoffspear

3

Один из вариантов может иметь свой собственный «файл-подобный» объект. На самом деле, cvs.writer требует для объекта только иметь метод write, так:

class PseudoFile(object): 
    def write(self, string): 
     # Do whatever with your string 

csv.writer(PseudoFile()).writerow(row) 

Вы пропуская пару шагов, но, возможно, это именно то, что вы хотите.

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