添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

问题

今天学习《Python Web 开发实战》 自定义转换器 这一小节,书中有段代码如下:

class ListConverter(BaseConverter):
    def __init__(self, url_map, separator="+"):
        super(ListConverter, self).__init__(url_map)
        self.separator = urllib.parse.unquote(separator)
    def to_python(self, value):
        return value.split(self.separator)
    def to_url(self, values):
        return self.separator.join(super(ListConverter, self).to_url(value)
                                   for value in values)

倒没什么问题,是可以正常运行的。

然而我对 super() 的用法不是很满意,毕竟在 Python3 环境下开发, super(ListConverter, self) 有硬编码嫌疑。于是代码修改如下:

class ListConverter(BaseConverter):
    def __init__(self, url_map, separator="+"):
        super().__init__(url_map)
        self.separator = urllib.parse.unquote(separator)
    def to_python(self, value):
        return value.split(self.separator)
    def to_url(self, values):
        return self.separator.join(super().to_url(value)
                                   for value in values)

结果一运行,解释器报错如下:
TypeError: super(type, obj): obj must be an instance or subtype of type

原因

经过多次尝试,发现问题出现在 self.separator.join(super().to_url(value) for value in values) 这段代码里。于是我做了个测试。

class A(object):
    def print_what(self, what):
        print(what)
class B(A):
    def print_what(self, what):
        [super() for __ in range(5)]
if __name__ == "__main__":
    b = B()
    b.print_what("hello")
------------------------------------
TypeError: super(type, obj): obj must be an instance or subtype of type

果然异常,当我将 super() 改为 super(B, self) 又一切正常。

是因为 super() 在一个成员函数中多次调用造成的吗?那就不用列表解析式,换寻常的循环语句:

class B(A):
    def print_what(self, what):
        for __ in range(5):
            super()

结果运行正常。

事实上,在成员函数中使用 super() 时,Python 会自动传参,我猜测是解析式影响了传进去的参数。但遗憾的是,我不知道该如何调试,才能获得错误情况下,传进去的参数是什么。

解决方案

针对此次遇到的问题,解决方法有以下三种。

第一种

使用 super(ListConverter, self) 代替 super()

第二种

不用解析式,用寻常的 for 循环。

class ListConverter(BaseConverter):
    def to_url(self, values):
        tmplist = []
        for value in values:
            tmplist.append(super().to_url(value))
        return self.separator.join(tmplist)

第三种

使用解析式,但不在解析式中调用 super()。

class ListConverter(BaseConverter):
    def to_url(self, values):
        sup = super()
        return self.separator.join(sup.to_url(value)
                                   for value in values)
  • Guan: 你是在哪儿看到报403的,我本地试了一下,可以正常访问,不过这个...
  • Veron: url=https://feed.hamibot.com/api...
  • Veron: 好东西,老Repo看着没更新怕用不了了,直接上你的版本,感谢:)
  • Guan: 这个很简单,你手动试一下就知道了
  • nigosim: 想请问一下,这个场景是B和网关还在同一网段,所以B仍能通过请求网...
  • youguanxinqing: scan 方法就是用来取值的
  • 第三: 但是取值却无法取啊
  • 九路: 测试
  • 396601500: 有用,帮到我了,谢谢
  • chauncey: 讲的很好,可以进一步讲一下vlan 和vxlan
  • Python 设计模式 Go MySQL vim c++ 继承 切片 指针 shell linux vscode 静态库 动态库 systemctl nginx rss 元类 类属性 私有属性 递归 汉诺塔 赏金问题 分支语句 循环语句 单例 跳转语句 赋值语句 defer type 项目管理 函数 闭包 结构体 数组 字典 异常机制 引用 方法 接口 匿名组合 排列 组合 动态规划 编辑距离 默认传参 递归中的参数 abc 抽象基类 ORM socket编程 简易聊天系统 select IO复用 并发编程 信号通道 enum vector std 友元 虚函数 动态联编 字符串处理 sed 平均负载 sftp 预处理 宏定义 条件编译 文件包含 操作符 预定义宏 其他命令 命名空间 导包 相对导入 pidstat vmstat 中断次数 上下文切换 lychee 编译 链接 mysqld ngx_fastdfs_module 真假值 去重 TypeError flutter 二分搜索 对角线问题 cpp 3n+1 缓存 mac 快捷键 终端 c centos7 docker 子域 主从配置 custom https http2 lychee-docker 创建型 django manjaro xfce databases k8s ssh log 网络 wireshark rust 多态 clickhouse trait 读书 编程 range 声明语句