我想做类似的事情:
import csv
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def post(self):
uploaded_csv_file = self.request.files['file'][0]
with uploaded_csv_file as csv_file:
for row in csv.reader(csv_file):
self.write(' , '.join(row))
但是,uploaded_csv_file
不属于file
类型。
这里的最佳做法是什么?
来源:
答案 0 :(得分:1)
正如the documentation所解释的那样:
csvfile
可以是任何支持迭代器协议的对象,并且每次调用其next()
方法时都返回一个字符串 - 文件对象和列表对象都是合适的。
所以,如果你有一些不是文件的东西,但它是一条线上的迭代器,那很好。如果它甚至不是线上的迭代器,只需将其包装成一个。对于一个简单的例子,如果它是read_all()
方法,你总是可以这样做:
uploaded_csv_file = self.request.files['file'][0]
contents = uploaded_csv_file.read_all()
lines = contents.splitlines()
for row in csv.reader(lines):
# ...
(显然你可以将各个步骤合并在一起使其更简洁;我只是将每个步骤作为一个单独的行编写,以使其更易于理解。)
当然,如果CSV文件很大,特别是如果它们需要一段时间才能到达并且你有一个很好的流媒体界面,你可能不希望这样一次读取整个事情。大多数网络服务器框架提供了很好的协议适配器,例如,获取字节流并为您提供线流。 (就此而言,即使是stdlib中的socket.makefile()
也是如此......)但在你的情况下,我认为这不是问题。