I have a Python script as follows:
我有一个Python脚本如下:
def VSH(GR, GRsand, GRshale):
'''Calculates Vsh from gamma inputs'''
value = (((GR-GRsand)/(GRshale-GRsand)))
if (value > 100.0):
value = 100.0
elif (value < 0.0):
value = 0.0
return value
From C# I have a loop that in IronPython 2.2 would extract the 3 arguments.
从C#我有一个循环,在IronPython 2.2中将提取3个参数。
foreach (string variableName in (PythonTuple)inputFunction.func_code.co_varnames)
{
// do something here
}
Now in IronPython 2.7.5 I get the names of the 4 variables, which makes sense, but breaks the old code. From the watch I get:
现在在IronPython 2.7.5中,我得到了4个变量的名称,这是有道理的,但打破了旧代码。从手表我得到:
co_varnames tuple, 4 items IronPython.Runtime.PythonTuple
[0] "GR" object {string}
[1] "GRsand" object {string}
[2] "GRshale" object {string}
[3] "value" object {string}
Looking at the object inputFunction.func_code in the debugger, I don't see anything that would return just the arguments. I do see the property co_argcount = 3. If I could be sure that the arguments were always first in the list of variables, then I could use it to filter out the local variables. Any suggestions?
查看调试器中的对象inputFunction.func_code,我没有看到任何只返回参数的东西。我确实看到属性co_argcount = 3.如果我可以确定参数总是在变量列表中的第一个,那么我可以用它来过滤掉局部变量。有什么建议么?
1 个解决方案
#1
1
Here's my solution:
这是我的解决方案:
// using System.Reflection;
dynamic func = scope.GetVariable("VSH");
var code = func.__code__;
var argNamesProperty = code.GetType().GetProperty("ArgNames", BindingFlags.NonPublic | BindingFlags.Instance);
string[] argNames = (string[])argNamesProperty.GetValue(code, null);
// argNames = ["GR", "GRsand", "GRshale"]
You were looking in the right place, but unfortunately the IronPython.Runtime.FunctionCode.ArgNames
property is private. With reflection, we can ignore that and just get the argument names anyway.
您正在寻找合适的位置,但不幸的是IronPython.Runtime.FunctionCode.ArgNames属性是私有的。通过反射,我们可以忽略它,并且无论如何只需获取参数名称。
Here's my complete test setup:
这是我完整的测试设置:
static void Main(string[] args)
{
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
ObjectOperations ops = engine.CreateOperations();
ScriptSource source = engine.CreateScriptSourceFromString(@"
def VSH(GR, GRsand, GRshale):
'''Calculates Vsh from gamma inputs'''
value = (((GR-GRsand)/(GRshale-GRsand)))
if (value > 100.0):
value = 100.0
elif (value < 0.0):
value = 0.0
return value");
CompiledCode compiled = source.Compile();
compiled.Execute(scope);
dynamic func = scope.GetVariable("VSH");
var code = func.__code__;
var argNamesProperty = code.GetType().GetProperty("ArgNames", BindingFlags.NonPublic | BindingFlags.Instance);
string[] argNames = (string[])argNamesProperty.GetValue(code, null);
// argNames = ["GR", "GRsand", "GRshale"]
}
I'm sure that you can trim down everything before the dynamic func = ...
line, because you probably have access to your VSH
function already.
我确信您可以在动态func = ...行之前减少所有内容,因为您可能已经可以访问您的VSH功能。
#1
1
Here's my solution:
这是我的解决方案:
// using System.Reflection;
dynamic func = scope.GetVariable("VSH");
var code = func.__code__;
var argNamesProperty = code.GetType().GetProperty("ArgNames", BindingFlags.NonPublic | BindingFlags.Instance);
string[] argNames = (string[])argNamesProperty.GetValue(code, null);
// argNames = ["GR", "GRsand", "GRshale"]
You were looking in the right place, but unfortunately the IronPython.Runtime.FunctionCode.ArgNames
property is private. With reflection, we can ignore that and just get the argument names anyway.
您正在寻找合适的位置,但不幸的是IronPython.Runtime.FunctionCode.ArgNames属性是私有的。通过反射,我们可以忽略它,并且无论如何只需获取参数名称。
Here's my complete test setup:
这是我完整的测试设置:
static void Main(string[] args)
{
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
ObjectOperations ops = engine.CreateOperations();
ScriptSource source = engine.CreateScriptSourceFromString(@"
def VSH(GR, GRsand, GRshale):
'''Calculates Vsh from gamma inputs'''
value = (((GR-GRsand)/(GRshale-GRsand)))
if (value > 100.0):
value = 100.0
elif (value < 0.0):
value = 0.0
return value");
CompiledCode compiled = source.Compile();
compiled.Execute(scope);
dynamic func = scope.GetVariable("VSH");
var code = func.__code__;
var argNamesProperty = code.GetType().GetProperty("ArgNames", BindingFlags.NonPublic | BindingFlags.Instance);
string[] argNames = (string[])argNamesProperty.GetValue(code, null);
// argNames = ["GR", "GRsand", "GRshale"]
}
I'm sure that you can trim down everything before the dynamic func = ...
line, because you probably have access to your VSH
function already.
我确信您可以在动态func = ...行之前减少所有内容,因为您可能已经可以访问您的VSH功能。