json.dumps() 在 python 2.7 中传递 str 子类的变量时给出意外结果 [英] json.dumps() give unexpected result when passing a variable of subclass of str in python 2.7

查看:65
本文介绍了json.dumps() 在 python 2.7 中传递 str 子类的变量时给出意外结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我像这样写了一个 str 的子类:

类 URL(str):def __init__(self, url):u = normalize_url(url)打印你super(URL, self).__init__(string=u)

normalize_url() 函数用于执行类似 url 编码的操作.一切正常,直到我使用 json.dumps().这是我的测试代码:

<预><代码>>>>u = URL('https://example.com/path contains space.html')https://example.com/path%20contains%20space.html>>>json.dumps(u)'"https://example.com/path 包含 space.html"'

为什么 json.dumps() 没有给出 'https://example.com/path%20contains%20space.html'

解决方案

str(与其他不可变对象一样)在 __new__

中进行初始化

python 中对象的构造大致如下:

inst = cls.__new__(cls, *args, **kwargs)cls.__init__(inst, *args, **kwargs)

在你的例子中,你调用了__init__,但是为时已晚,对象已经在__new__

不过你可以解决这个问题!:

类 URL(str):__slots__ = ()def __new__(cls, val):val = val.replace(' ', '%20')return super(URL, cls).__new__(cls, val)

现在可以了!

<预><代码>>>>x = URL('foo bar')>>>X'foo%20bar'>>>json.dumps(x)'"foo%20bar"'

请注意,我添加了 __slots__ = () 以恢复 str 具有的不变性.

I wrote a subclass of str like this:

class URL(str):
    def __init__(self, url):
        u = normalize_url(url)
        print u
        super(URL, self).__init__(string=u)

normalize_url() function is used for doing something like url encoding. Everything is ok, until I use json.dumps(). Here is my test code:

>>> u = URL('https://example.com/path contains space.html')
https://example.com/path%20contains%20space.html
>>> json.dumps(u)
'"https://example.com/path contains space.html"'

Why json.dumps() didn't give 'https://example.com/path%20contains%20space.html'

解决方案

str (like other immutable objects) does it's initialization in __new__

Construction of an object in python roughly looks like this:

inst = cls.__new__(cls, *args, **kwargs)
cls.__init__(inst, *args, **kwargs)

In your example, you call __init__, but it is too late, the object has already been set up in __new__

You can however fix this!:

class URL(str):
    __slots__ = ()

    def __new__(cls, val):
         val = val.replace(' ', '%20')
         return super(URL, cls).__new__(cls, val)

Now it works!

>>> x = URL('foo bar')
>>> x
'foo%20bar'
>>> json.dumps(x)
'"foo%20bar"'

Note that I've added __slots__ = () to restore the immutability that str had.

这篇关于json.dumps() 在 python 2.7 中传递 str 子类的变量时给出意外结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆