You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyO3中如何为继承PyDict的类实现带自定义参数的构造器?

解决PyO3继承PyDict时构造器的TypeError问题

问题根源

当你通过extends=PyDict继承Python内置dict时,Python会默认遵循原生dict的初始化逻辑——如果只传入一个参数,它会尝试将这个参数当作可迭代对象(比如键值对序列)来初始化字典。你传入的整数会被原生dict的构造逻辑误判为可迭代对象,从而抛出"int is not iterable"错误。哪怕自定义了new方法,也必须正确衔接父类的初始化流程,否则会触发这个问题。

解决方案

1. 正确实现自定义构造器

在Rust中,继承PyDict需要使用PyClassInitializer组合父类和子类的初始化逻辑,不能直接返回子类实例。先初始化父类PyDict,再传入子类的自定义字段值,同时实现__missing__方法完成defaultdict的核心功能。

示例代码:

use pyo3::prelude::*;
use pyo3::types::PyDict;

#[pyclass(extends=PyDict)]
struct PyDefaultDict {
    default_value: i32,
}

#[pymethods]
impl PyDefaultDict {
    #[new]
    fn new(default_value: i32) -> PyResult<PyClassInitializer<Self>> {
        // 先初始化父类PyDict,再绑定子类字段
        Ok(PyClassInitializer::from(PyDict::new())
            .add_subclass(Self { default_value }))
    }

    // 实现__missing__方法,访问不存在的键时返回默认值
    #[pyo3(name = "__missing__")]
    fn missing(&self, _key: &PyAny) -> PyResult<i32> {
        Ok(self.default_value)
    }
}

#[pymodule]
fn defaultdict_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    m.add_class::<PyDefaultDict>()?;
    Ok(())
}

2. Python端调用方式

现在直接传入整数默认值即可正常使用,不会触发迭代错误:

from defaultdict_module import PyDefaultDict

dd = PyDefaultDict(0)
print(dd["unexisting_key"])  # 输出0
dd["existing_key"] = 100
print(dd["existing_key"])     # 输出100

扩展:支持原生dict的初始化参数

如果需要像原生dict一样接收可迭代参数初始化,可以修改new方法,手动处理可选的可迭代参数并插入到父类PyDict中:

#[new]
fn new(default_value: i32, iterable: Option<&PyAny>) -> PyResult<PyClassInitializer<Self>> {
    let dict = PyDict::new();
    if let Some(iter) = iterable {
        // 遍历可迭代对象,插入键值对到PyDict
        for item in iter.iter()? {
            let (k, v) = item?.extract()?;
            dict.set_item(k, v)?;
        }
    }
    Ok(PyClassInitializer::from(dict)
        .add_subclass(Self { default_value }))
}

Python端即可同时支持两种初始化方式:

# 仅传默认值
dd1 = PyDefaultDict(0)
# 传默认值+初始化键值对
dd2 = PyDefaultDict(0, [("a", 1), ("b", 2)])

内容的提问来源于stack exchange,提问作者davidA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:48:24