C#动态调用Python脚本传参时出现'str is not callable'报错
问题原因
- 直接报错根因:
ops.Invoke("CalcAdd", obj)第一个参数传入了字符串类型的方法名,Invoke方法要求第一个入参是可调用的Python函数对象,而非字符串标识,所以抛出str is not callable错误 - 冗余代码问题:你先编译执行了脚本,又调用了一次
ExecuteFile,属于重复执行,无实际意义 - 可变参数兼容问题:当前Python侧的
CalcAdd仅固定接受2个参数,要支持2、3、4个乃至更多动态参数,需要调整Python函数写法
修正后的代码
Python脚本调整(支持任意数量参数)
# 可接收任意数量输入参数的加法函数 class AddTest: def CalcAdd(self, *args): return sum(args)
C#代码调整
var engine = Python.CreateEngine(); var scope = engine.CreateScope(); ObjectOperations ops = engine.CreateOperations(); try { // 单次执行Python脚本即可,无需重复执行 engine.ExecuteFile(@"C:\Nidec\PythonScript\download_nrlist.py", scope); var variables = scope.GetVariableNames().Where(x => !x.Contains("_")).ToList(); var className = variables.FirstOrDefault(); if (className == null) return; // 实例化Python类 var cls = scope.GetVariable(className); var clsInstance = ops.CreateInstance(cls); // 获取方法的参数列表 var method = ops.GetMember(clsInstance, "CalcAdd"); var func = ops.GetMember(method, "__func__"); var argNames = func.GetType() .GetProperty("ArgNames", BindingFlags.Instance | BindingFlags.NonPublic)? .GetValue(func, null) as string[]; if (argNames == null) return; // 生成对应数量的测试参数(减去self参数) int paramCount = argNames.Length - 1; object[] parameters = new object[paramCount]; for (int i = 0; i < paramCount; i++) { parameters[i] = i + 1; } // 修正调用方式:传入可调用的method对象,而非字符串 var ccResult = ops.Invoke(method, parameters); } catch (Exception ex) { // 自定义异常处理逻辑 Console.WriteLine(ex.Message); }
额外说明
如果更习惯用简化写法,也可以直接用IronPython支持的dynamic语法调用方法,无需手动处理ObjectOperations的反射逻辑:
dynamic clsInstance = ops.CreateInstance(cls); var ccResult = clsInstance.CalcAdd(1,2,3,4); // 直接传任意数量参数即可
内容的提问来源于stack exchange,提问作者Eswar reddy
相关产品推荐
相关产品推荐

