IronPython中的所有班级成员

时间:2020-06-13 09:26:48

标签: c# ironpython

我目前正在为游戏编写脚本系统,我想用C#定义一个基类,该基类可以从Python派生。但是,在执行脚本之后,我想访问Python类中动态添加的成员变量(名称,类型和值)。因此,我希望能够创建savegames(通过存储所有变量的值)。这是我做过的一次尝试:

Engine = Python.CreateEngine();
Scope = Engine.CreateScope();
ScriptSource scriptSource = Engine.CreateScriptSourceFromString(@"from MyEngine import Foo

class Foo2(Foo):
    newProp = 'This is a property'    # This should be added to _dynamicMembers
");

scriptSource.Execute(Scope);
dynamic foo2 = Scope.GetVariable("Foo2");
dynamic foo2_instance = foo2();    // 'newProp' is visible in the debugger....
dynamic foo2_instance_props = foo2_instance._dynamicMembers;    // ...but somehow not added to _dynamicMembers

其中基类Foothis blog post中的基类相似:

public class Foo : DynamicObject
{
    public Dictionary<string, object> _dynamicMembers = new Dictionary<string, object>();

    public Foo()
    {}

    // These Try*Member methods are never called from 'Foo2'
    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    {
        Debug.WriteLine("TryGetMember");
        return _dynamicMembers.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        Debug.WriteLine("TrySetMember");
        if (_dynamicMembers.ContainsKey(binder.Name))
        {
            _dynamicMembers[binder.Name] = value;
            return true;
        }

        return base.TrySetMember(binder, value);
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args,
    out object result)
    {
        Debug.WriteLine("TryInvokeMember");
        return base.TryInvokeMember(binder, args, out result);
    }
}

但是如前面的逗号所示,没有添加新变量newProp,也没有调用方法TryGetMemberTrySetMemberTryInvokeMember。我尝试了更多的方法,例如访问元对象:

SourceUnit sourceUnit = HostingHelpers.GetSourceUnit(scriptSource)
Parser parser = Parser.CreateParser(new CompilerContext(sourceUnit, Engine.GetCompilerOptions(), ErrorSink.Default),(PythonOptions)LangContext.Options);
PythonAst ast = parser.ParseFile(false);
dynamic memNames = foo2.GetMetaObject(ast).GetDynamicMemberNames(); //Works but contains all kinds of methods from subclasses + how do I get values and types now?

或使用C#反射:

foreach (var property in foo2.GetType().GetProperties()) // Doesn't return the member variables
{
    Debug.WriteLine("Name = " + property.Name + ", Type = " + property.PropertyType);
    Debug.WriteLine("Attr = " + property.Attributes);
}

所以我的问题是:如何实现第一段中描述的目标?另外,我想直接访问Python类的静态成员变量列表(即foo2.newProp而不是foo2_instance.newProp),所以我不想创建一个Foo2的实例来访问_dynamicMembers。 提前非常感谢!

0 个答案:

没有答案