UrlSplitResult:无法_replace字段



我正试图通过拆分-注入-连接:将基本身份验证注入到url中

url = urllib.parse.urlsplit(url)
new_url = url._replace(username=user, password=password)

但我对我从urllib.parse.urlsplit方法得到的SplitResult的行为感到惊讶:

>>> v = urlsplit('http://a.b/c/d')
>>> v.username is None and v.password is None  # None, but accessible
True
>>> v._replace(scheme='ftp')  # beautiful!  Just like expected.
SplitResult(scheme='ftp', netloc='a.b', path='/c/d', query='', fragment='')
# however...
>>> v._replace(scheme='ftp', username='u', password='p')
...ValueError: Got unexpected field names: ['username', 'password']

这个SplitResult中的None字段似乎无法替换。这很奇怪,因为文档声称它是一个命名元组。

当我对一个自建的命名元组执行等效操作时,似乎可以毫无问题地替换'None'字段

>>> T = namedtuple("T", ("a", "b", "c"))
>>> t = T(a=1, b=2, c=None)
>>> t
T(a=1, b=2, c=None)
>>> t._replace(c=3)
T(a=1, b=2, c=3)

但是,通过替换未存在的字段也可以触发相同的异常。

>>> t._replace(d=4)  # should raise, please
...ValueError: Got unexpected field names: ['d']
# I was expecting an AttributeError, but hey...

然而,在这种情况下,意外字段实际上是不可访问的:

>>> t.d is None
...AttributeError: 'T' object has no attribute 'd'

知道SplitResult有什么不同吗?

文档没有列出字段usernamepasswordhostnameport的索引。这表明它们实际上不是命名元组的一部分,而是SplitResult对象的属性。在CPython实现中,SplitResult似乎继承了包含前几个具有索引的字段的namedtuple,以及添加其他字段作为属性的mixin。

最新更新