Flask JSONEncoder将ensure_ascii设置为False

时间:2021-03-22 20:28:00

I'm working on a small flask app in which I want to return strings containing umlauts (in general German special characters, e.g 'ß'). As the default JSONEncoder in flask has ensure_ascii=True, this will always convert my string

我正在研究一个小瓶子应用程序,我想在其中返回包含变音符号的字符串(通常是德语特殊字符,例如'ß')。由于flask中的默认JSONEncoder具有ensure_ascii = True,因此将始终转换我的字符串

Hauptstraße 213

to this:

Hauptstra\u00dfe 213

My first approach was to just create a very basic custom JSONEncoder

我的第一个方法是创建一个非常基本的自定义JSONEncoder

class NonAsciiJSONEncoder(json.JSONEncoder):
    def __init__(self, **kwargs):
        super(NonAsciiJSONEncoder, self).__init__(kwargs)
        self.ensure_ascii = False 

If I use this, by setting

如果我使用它,通过设置

app.json_encoder = NonAsciiJSONEncoder

my return jsonify(...) will actually return the string containing 'ß'.

我的返回jsonify(...)实际上会返回包含'ß'的字符串。

However, as ensure_ascii is an attribute of the default Encoder, I thought it might be better to just change it by setting it to False

但是,由于ensure_ascii是默认编码器的属性,我认为通过将其设置为False来更改它可能会更好

app.json_encoder.ensure_ascii = False

This will actually set the property to False which I checked before returning. But somehow, the string is still returned without 'ß' but with \u00df.

这实际上将属性设置为False,我在返回之前检查了它。但不知何故,字符串仍然返回没有'ß'但是使用\ u00df。

How can this be, as all I'm doing in my custom Encoder, is setting this attribute to False?

这怎么可能,正如我在自定义编码器中所做的那样,将此属性设置为False?

1 个解决方案

#1


7  

You are setting a class attribute when altering app.json_encoder.ensure_ascii, which is not the same thing as an instance attribute.

在更改app.json_encoder.ensure_ascii时设置类属性,这与实例属性不同。

The JSONEncoder.__init__ method sets an instance attribute to True, as that is the default value for the ensure_ascii argument. Setting the class attribute won't prevent the __init__ method from setting an instance attribute, and it is the instance attribute that wins here.

JSONEncoder .__ init__方法将实例属性设置为True,因为这是ensure_ascii参数的默认值。设置class属性不会阻止__init__方法设置实例属性,而是在此处获胜的实例属性。

You could just have your subclass set the argument to False:

你可以让你的子类将参数设置为False:

class NonASCIIJSONEncoder(json.JSONEncoder):
    def __init__(self, **kwargs):
        kwargs['ensure_ascii'] = False
        super(NonASCIIJSONEncoder, self).__init__(**kwargs)

#1


7  

You are setting a class attribute when altering app.json_encoder.ensure_ascii, which is not the same thing as an instance attribute.

在更改app.json_encoder.ensure_ascii时设置类属性,这与实例属性不同。

The JSONEncoder.__init__ method sets an instance attribute to True, as that is the default value for the ensure_ascii argument. Setting the class attribute won't prevent the __init__ method from setting an instance attribute, and it is the instance attribute that wins here.

JSONEncoder .__ init__方法将实例属性设置为True,因为这是ensure_ascii参数的默认值。设置class属性不会阻止__init__方法设置实例属性,而是在此处获胜的实例属性。

You could just have your subclass set the argument to False:

你可以让你的子类将参数设置为False:

class NonASCIIJSONEncoder(json.JSONEncoder):
    def __init__(self, **kwargs):
        kwargs['ensure_ascii'] = False
        super(NonASCIIJSONEncoder, self).__init__(**kwargs)