Python 3 如何解决 urllib.parse.urlencode 在 Python 3.4.2 中缺少 quote_via

Python 3 How to workaround urllib.parse.urlencode missing quote_via in Python 3.4.2

我在机器 运行ning Python 3.5.2 上创建了一个 Python 脚本。现在我想 运行 在另一台计算机 运行ning Python 3.4.2 上安装它,但我无法在那里升级 Python。 我的问题是我使用了

urllib.parse.urlencode(dict, safe='/', quote_via=urllib.parse.quote)

quote_via选项显然在Python3.4.2中不可用,所以报错

TypeError: urlencode() got an unexpected keyword argument 'quote_via'

我需要在这里对字典 dict 进行 urlencode,仅使用 quote() 而不是 quote_plus(),这是 3.4 和 3.5 中的默认设置。但是,似乎只有 3.5 有可能覆盖默认值。

我该如何解决这个问题?

实现您自己的 urlencode() 功能。 urllib.parse.urlencode() library function 主要由测试组成,以确保可以处理 bytesstr 对象,以及处理 doseq 标志。

否则,它只不过是一个循环,对每对的键和值进行编码,在它们之间添加 =,然后将所有这些对与 & 连接起来。为您的输入实现相同的循环,并硬编码您需要的变体。

您可以通过以下方式复制您的特定行为:

'&'.join(['{}={}'.format(quote(k, safe='/'), quote(v, safe='/'))
          for k, v in dict.items()])

肮脏的破解方法:)

import urllib.parse
import sys
major, minor, _, _, _ = sys.version_info
if major == 3 and minor < 5:
    urllib.parse.quote_plus = urllib.parse.quote

更新:稍微不那么脏:

class MonkeyPatchQuote(object):
    def __init__(self):
        major, minor, _, _, _ = sys.version_info
        self.should_patch = major == 3 and minor < 5

    def __enter__(self):
        if self.should_patch:
            self.original_handler = urllib.parse.quote_plus
            urllib.parse.quote_plus = urllib.parse.quote

    def __exit__(self, *args):
        if self.should_patch:
            urllib.parse.quote_plus = self.original_handler