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

调用PyObject_VectorcallMethod报错:Class.set_params()参数'a'多值冲突

问题原因分析

你遇到的TypeError是因为C代码中参数传递方式完全错误,导致Python的set_params函数同时收到了a的位置参数和关键字参数,触发重复参数报错。具体错误点:

  • 参数打包错误:用Py_BuildValue("i", 77, "i", 20)生成参数完全错误,格式字符串与参数数量不匹配,且PyObject_VectorcallMethod不需要将参数打包成单个对象,需直接将参数值放入args数组。
  • args数组构造错误:你把错误打包的keyfunc作为位置参数传递,同时指定了kwnames,导致函数既收到位置参数(77被当作a的位置值)又收到a=77的关键字参数,造成重复。
  • nargsf计算错误:错误设置了位置参数数量,未正确标记关键字参数的数量。
修正后的C代码
// 创建方法名
PyObject *name = Py_BuildValue("s", "set_params");
// 创建关键字参数名称元组
PyObject *kwnames = Py_BuildValue("(s,s)", "a", "b");
// 准备参数值:实例 + 关键字参数值(顺序与kwnames对应)
PyObject *arg_a = PyLong_FromLong(77);
PyObject *arg_b = PyLong_FromLong(20);
PyObject *args[] = { pInstance, arg_a, arg_b };

// 计算nargsf:0个位置参数 | 2个关键字参数 | 包含实例标志
size_t nargsf = 0 | (2 << PY_VECTORCALL_KW_SHIFT) | PY_VECTORCALL_ARGUMENTS_OFFSET;
// 调用方法
PyObject *ret = PyObject_VectorcallMethod(name, args, nargsf, kwnames);

// 释放引用
Py_DECREF(arg_a);
Py_DECREF(arg_b);
Py_DECREF(kwnames);
Py_DECREF(name);
关键说明
  • args数组结构:第一个元素是实例对象,后面依次是位置参数值(如有),再后面是关键字参数值(顺序必须与kwnames中的名称一一对应)。
  • nargsf计算规则:
    • 低8位(PY_VECTORCALL_ARGUMENTS_MASK)是位置参数的数量(不含实例)。
    • 关键字参数数量通过kw_count << PY_VECTORCALL_KW_SHIFT计算。
    • PY_VECTORCALL_ARGUMENTS_OFFSET标志表示args[0]是实例对象(方法调用必须带此标志)。
  • 所有通过PyLong_FromLong等函数创建的临时对象,必须手动调用Py_DECREF释放,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:12:13