json.dumps() 在 python 2.7 中传递 str 子类的变量时给出意外结果 [英] json.dumps() give unexpected result when passing a variable of subclass of str in python 2.7
问题描述
我像这样写了一个 str 的子类:
类 URL(str):def __init__(self, url):u = normalize_url(url)打印你super(URL, self).__init__(string=u)
normalize_url()
函数用于执行类似 url 编码的操作.一切正常,直到我使用 json.dumps()
.这是我的测试代码:
为什么 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屋!