Python Flask,TypeError:'dict'对象不可调用

46

我遇到了一个问题,似乎是很常见的问题,但是我已经进行了研究,没有看到它在任何地方被准确地重现。当我打印json.loads(rety.text)时,我看到了我需要的输出。但是当我调用return时,它会显示这个错误。有什么想法吗?非常感谢您的帮助。我正在使用 Flask MethodHandler

class MHandler(MethodView):
    def get(self):
        handle = ''
        tweetnum = 100

        consumer_token = '' 
        consumer_secret = ''
        access_token = '-'
        access_secret = ''

        auth = tweepy.OAuthHandler(consumer_token,consumer_secret)
        auth.set_access_token(access_token,access_secret)

        api  = tweepy.API(auth)

        statuses = api.user_timeline(screen_name=handle,
                          count= tweetnum,
                          include_rts=False)

        pi_content_items_array = map(convert_status_to_pi_content_item, statuses)
        pi_content_items = { 'contentItems' : pi_content_items_array }

        saveFile = open("static/public/text/en.txt",'a') 
        for s in pi_content_items_array: 
            stat = s['content'].encode('utf-8')
            print stat

            trat = ''.join(i for i in stat if ord(i)<128)
            print trat
            saveFile.write(trat.encode('utf-8')+'\n'+'\n')

        try:
            contentFile = open("static/public/text/en.txt", "r")
            fr = contentFile.read()
        except Exception as e:
            print "ERROR: couldn't read text file: %s" % e
        finally:
            contentFile.close()
        return lookup.get_template("newin.html").render(content=fr) 

    def post(self):
        try:
            contentFile = open("static/public/text/en.txt", "r")
            fd = contentFile.read()
        except Exception as e:
            print "ERROR: couldn't read text file: %s" % e
        finally:
                contentFile.close()
        rety = requests.post('https://gateway.watsonplatform.net/personality-insights/api/v2/profile', 
                auth=('---', ''),
                headers = {"content-type": "text/plain"},
                data=fd
            )

        print json.loads(rety.text)
        return json.loads(rety.text)


    user_view = MHandler.as_view('user_api')
    app.add_url_rule('/results2', view_func=user_view, methods=['GET',])
    app.add_url_rule('/results2', view_func=user_view, methods=['POST',])

以下是跟踪信息(请注意,结果已经在上方打印出来):

Traceback (most recent call last):
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/flask/app.py", line 1478, in full_dispatch_request
    response = self.make_response(rv)
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/flask/app.py", line 1577, in make_response
    rv = self.response_class.force_type(rv, request.environ)
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/werkzeug/wrappers.py", line 841, in force_type
    response = BaseResponse(*_run_wsgi_app(response, environ))
  File "/Users/RZB/anaconda/lib/python2.7/site-packages/werkzeug/test.py", line 867, in run_wsgi_app
    app_rv = app(environ, start_response)

1
今天在2021年,要解决这个问题,您只需要使用以下命令将flask升级到v2.x: pip install flask --upgrade 或者 python3 -m pip install flask --upgrade - YannXplorer
5个回答

70

Flask 在视图函数中只期望返回一个类似响应对象的东西。 这意味着一个 Response 对象,一个字符串或者一个描述 body、状态码以及 headers 的元组。而您返回了一个字典,这不是上述三个之一。既然您要返回 JSON 数据,那就返回一个 body 内容为 JSON 字符串、content type 为 application/json 的 Response 对象吧。

return app.response_class(rety.content, content_type='application/json')

在您的示例中,您已经有了一个JSON字符串,这是您进行请求后返回的内容。但是,如果您想将Python结构转换为JSON响应,请使用jsonify
data = {'name': 'davidism'}
return jsonify(data)

在幕后,Flask是一个WSGI应用程序,它期望传递可调用对象,这就是为什么你会得到那个特定的错误:字典不可调用,而Flask不知道如何将其转换为可调用对象。
在幕后,Flask是一个WSGI应用程序,期望传递可调用对象,这就是为什么您会看到这个特定的错误:字典不是可调用的,并且Flask不知道该怎样将其转换为可调用对象。

27

使用 Flask.jsonify 函数返回数据。

from flask import jsonify 
# ...
return jsonify(data)

6
如果您从Flask视图返回数据、状态、头元组,当数据已经是响应对象时(例如jsonify返回的内容),Flask当前会忽略状态代码和content_type标头。
这不会设置content-type标头:
headers = {
    "Content-Type": "application/octet-stream",
    "Content-Disposition": "attachment; filename=foobar.json"
}
return jsonify({"foo": "bar"}), 200, headers

相反,使用flask.json.dumps生成数据(这也是jsonfiy内部使用的方法)。

from flask import json

headers = {
    "Content-Type": "application/octet-stream",
    "Content-Disposition": "attachment; filename=foobar.json"
}
return json.dumps({"foo": "bar"}), 200, headers

或者与响应对象一起使用:

response = jsonify({"foo": "bar"})
response.headers.set("Content-Type", "application/octet-stream")
return response

然而,如果您想要按照这些示例所展示的文字量直接提供 JSON 数据下载,则应使用 send_file

from io import BytesIO
from flask import json
data = BytesIO(json.dumps(data))
return send_file(data, mimetype="application/json", as_attachment=True, attachment_filename="data.json")

2

0

不要试图将响应转换为 JSON,这样做是可行的。

return response.content

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接