在GoogleAppEngine中如何正确地从文件生成json?

1 投票
2 回答
575 浏览
提问于 2025-04-15 13:35

我刚开始学习Python和GAE(谷歌应用引擎),有没有人能帮我提供一些示例代码,来完成一个简单的任务?我已经能读取一个简单的文件并把它输出为网页了,但我需要一些稍微复杂一点的逻辑。下面是伪代码:

  open file;
  for each line in file {
    store first line as album title;
    for each song read {
      store first line as song title;
      store second line as song URL;
    }
  }
  Output the read in data as a json;

这个文件的格式大概是这样的:

专辑标题1
歌曲1标题
歌曲1网址
歌曲2标题
歌曲2网址

专辑标题2
歌曲1标题
歌曲1网址
歌曲2标题
歌曲2网址
..

2 个回答

1

在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这些问题可能是因为我们没有正确理解某些概念或者用错了方法。对于初学者来说,理解这些概念是非常重要的,因为它们是编程的基础。

比如说,变量就像一个盒子,我们可以把不同的东西放进去,随时取出来使用。函数则像是一个机器,我们把原料放进去,它会给我们一个结果。理解这些基本概念后,我们就能更好地写出正确的代码。

当我们在编写代码时,遇到问题时,可以去一些技术论坛,比如StackOverflow,看看其他人是怎么解决类似问题的。这里有很多经验丰富的程序员,他们分享了自己的解决方案和经验,帮助我们更快地找到问题的根源。

总之,编程是一项需要不断学习和实践的技能,遇到问题时不要气馁,积极寻找解决方案,慢慢就会变得越来越熟练。

from django.utils import simplejson

def albums(f):
  "" yields lists of strings which are the
     stripped lines for an album (blocks of
     nonblank lines separated by blocks of
     blank ones.
  """
  while True:
    # skip leading blank lines if any
    for line in f:
      if not line: return
      line = line.strip()
      if line: break
    result = [line]
    # read up to next blank line or EOF
    for line in f:
      if not line:
        yield result
        return
      line = line.strip()
      if not line: break
      result.append(line)
    yield result

def songs(album):
  """ yields lists of 2 lines, one list per song.
  """
  for i in xrange(1, len(album), 2):
    yield (album[i:i+2] + ['??'])[:2]

result = dict()
f = open('thefile.txt')
for albumlines in albums(f):
  current = result[albumlines[0]] = []
  for songlines in songs(albumlines):
    current.append( {
      'songtitle': songlines[0],
      'songurl': songlines[1]
    } )

response.out.write(simplejson.dumps(result))
3

这里有一个基于生成器的解决方案,具有一些不错的特点:

  • 可以处理文本文件中相邻专辑之间的多个空行
  • 可以处理文本文件开头和结尾的空行
  • 一次只使用一张专辑所需的内存
  • 展示了很多用Python可以做的有趣事情 :)

albums.txt

Album title1
song1 title
song1 url
song2 title
song2 url

Album title2
song1 title
song1 url
song2 title
song2 url

代码

from django.utils import simplejson

def gen_groups(lines):
   """ Returns contiguous groups of lines in a file """

   group = []

   for line in lines:
      line = line.strip()
      if not line and group:
         yield group
         group = []
      elif line:
         group.append(line)


def gen_albums(groups):
   """ Given groups of lines in an album file, returns albums  """

   for group in groups:
      title    = group.pop(0)
      songinfo = zip(*[iter(group)]*2)
      songs    = [dict(title=title,url=url) for title,url in songinfo]
      album    = dict(title=title, songs=songs)

      yield album


input = open('albums.txt')
groups = gen_groups(input)
albums = gen_albums(groups)

print simplejson.dumps(list(albums))

输出

[{"songs": [{"url": "song1 url", "title": "song1 title"}, {"url": "song2 url", "title": "song2 title"}], "title": "song2
title"},
{"songs": [{"url": "song1 url", "title": "song1 title"}, {"url": "song2 url", "title": "song2 title"}], "title": "song2
title"}]

然后可以像这样在Javascript中访问专辑信息:

var url = albums[1].songs[0].url;

最后,这里有一个关于那个复杂的zip函数的说明。

撰写回答