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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34057851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:25:11  来源:igfitidea点击:

Python Flask, TypeError: 'dict' object is not callable

pythonjsonflask

提问by puhtiprince

Having an issue that seems to be common yet I have done my research and don't see it being exactly recreated anywhere. When I print json.loads(rety.text), I am seeing the output I need. Yet when I call return, it shows me this error. Any ideas? Help is greatly appreciated and thank you. I am using the Flask MethodHandler.

有一个似乎很常见的问题,但我已经完成了我的研究,并没有看到它在任何地方完全重现。当我打印时json.loads(rety.text),我看到了我需要的输出。然而,当我调用返回时,它向我显示了这个错误。有任何想法吗?非常感谢并感谢您的帮助。我正在使用 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',])

Here is the Traceback(Keep in mind results are printing above):

这是回溯(请记住上面打印的结果):

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)

采纳答案by davidism

Flask only expects views to return a response-like object.This means a Response, a string, or a tuple describing the body, code, and headers. You are returning a dict, which is not one of those things. Since you're returning JSON, return a response with the JSON string in the body and a content type of application/json.

Flask 只期望视图返回一个类似响应的对象。这意味着Response描述主体、代码和标题的、字符串或元组。您正在返回一个 dict,这不是其中之一。由于您要返回 JSON,因此请返回正文中包含 JSON 字符串且内容类型为application/json.

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


In your example, you already have a JSON string, the content returned by the request you made. However, if you want to convert a Python structure to a JSON response, use jsonify:

在您的示例中,您已经有一个 JSON 字符串,即您发出的请求返回的内容。但是,如果要将 Python 结构转换为 JSON 响应,请使用jsonify

data = {'name': 'davidism'}
return jsonify(data)


Behind the scenes, Flask is a WSGI application, which expects to pass around callable objects, which is why you get that specific error: a dict isn't callable and Flask doesn't know how to turn it into something that is.

在幕后,Flask 是一个 WSGI 应用程序,它期望传递可调用对象,这就是为什么您会收到特定错误的原因:dict 不可调用且 Flask 不知道如何将其转换为可调用对象。

回答by Sahil Shah

Use the Flask.jsonify function to return the data.

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

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

回答by firelynx

If you return a data, status, headerstuple from a Flask view, Flask currently ignores the status code and content_typeheader when the data is already a response object, such as what jsonifyreturns.

如果data, status, headers从 Flask 视图返回一个元组,content_type当数据已经是响应对象时,Flask 当前会忽略状态代码和标头,例如jsonify返回的内容。

This doesn't set the content-type header:

这不会设置内容类型标头:

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

Instead, use flask.json.dumpsto generate the data (which is what jsonfiyuses internally).

相反,用于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

Or work with the response object:

或者使用响应对象:

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

However, if you want to literally do what these examples show and serve JSON data as a download, use send_fileinstead.

但是,如果您想真正按照这些示例显示的内容提供 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")

回答by l3o

Instead of trying to jsonify the response, this worked.

这没有尝试对响应进行 jsonify,而是有效。

return response.content

回答by buncis

as for flask version 1.1.0 now you could return dict

至于烧瓶版本 1.1.0 现在你可以返回 dict

flask will convert it automatically to json response.

flask 会自动将其转换为 json 响应。

https://flask.palletsprojects.com/en/1.1.x/quickstart/#apis-with-jsonhttps://flask.palletsprojects.com/en/1.1.x/changelog/#version-1-1-0

https://flask.palletsprojects.com/en/1.1.x/quickstart/#apis-with-json https://flask.palletsprojects.com/en/1.1.x/changelog/#version-1-1-0