【问题标题】:Flask jsonify: object is not iterableFlask jsonify:对象不可迭代
【发布时间】:2014-01-07 06:21:51
【问题描述】:

我的课程如下所示:

class Sound(SoundJsonSerializer):
    def __init__(self, name, length):
        self.name = name
        self.length = length

SoundJsonSerializer 使我的自定义 JSONEncoder 可以将此对象序列化为 JSON:

{
    "name": "foobar",
    "length": 23.4
}

现在我希望我的一个请求能够准确地响应上述 JSON。

@app.route('/sounds/<soundid>')
def get_sound(soundid):
    s = Sound("foobar", 23.4)
    return jsonify(s)

产生一个错误,声称 s 不可迭代,这是真的。如何使该方法返回我想要的 JSON?

我知道我可以通过像这样从我的Sound 对象显式创建一个字典来做到这一点:

    return jsonify({"name": s.name, "length": s.length})

但这对我来说真的很难看。实现目标的首选方式是什么?

【问题讨论】:

  • 其实我更喜欢你认为“丑陋”的方式。如果您经常这样做,那么也许将字典的创建变成一个函数,该函数接受对象和代表您想要包含(或可能排除)的属性的字符串列表并创建字典(使用 dir() 和 @987654329 @)。
  • 是的,这个问题很烦人,所以我决定patch Flask to make it work

标签: python json flask


【解决方案1】:

你可以试试这个解决方法:

class Sound():
    def __init__(self, name, length):
        self.name = name
        self.length = length

@app.route('/sounds/<soundid>')
def get_sound(soundid):
    s = Sound('foobar', 23.4)
    return jsonify(s.__dict__)

【讨论】:

  • 这不是一个好习惯,因为它暴露了所有的类内部,而不仅仅是他想要的属性
  • @PaoloCasciello 是对的,在 JSON 表示中可能只有我想要的属性子集。这就是我的自定义 JSONEncoder 负责的工作。
【解决方案2】:

您可以通过几种不同的方式执行此操作。确保您只返回您想要的最安全的方法是这样做:

class Sound():
    name = None
    length = None
    test = "Test"

    def __init__(self, name, length):
        self.name = name
        self.length = length

@admin_app.route('/sounds/<sound_id>')
def get_sound(sound_id):
    s = Sound('foobar', sound_id)
    return jsonify(vars(s))

通过将 name = None, length = None 定义为类级别变量的一部分,您可以使用 vars() 与 __dict__

当您通过__init__ 实例化类并在那里设置变量时,jsonify 将只返回您通过__init__ 设置的内容。

上面代码的结果:

{
"length": "1",
"name": "foobar"
}

【讨论】:

    猜你喜欢
    • 2012-08-01
    • 2014-02-20
    • 1970-01-01
    • 2021-12-25
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    相关资源
    最近更新 更多