[IronPython] Calling Python objects from C#?

michael_sweeney at agilent.com michael_sweeney at agilent.com
Mon Jan 15 21:54:44 CET 2007


Thanks Dino,

That is much simpler! Now for get/set of attributes values...

I need an ICallerContext for the Ops.GetAttr() call. Is there a way to get this without calling 'object pmodule = module.Import("MyExample");'?

 
        static void Main(string[] args)
        {
            PythonEngine engine = new PythonEngine();
            EngineModule module = engine.CreateModule("MyExample", true);

            try
            {
                engine.ExecuteFile("MyExample.py", module);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to execute Example.py file");
                Console.WriteLine("Exception: {0}", ex.Message);
                return;
            }

            // Get the Python Class from the module's global list
            object ptype = module.Globals["MyClass"];

            // Get Module Instance
            object pmodule = module.Import("MyExample");

            // Create an instance of the object
            object pobj = Ops.Call(ptype);

            // Call the method - Using Ops.Invoke()
            object rtnValue = Ops.Invoke(pobj,
			 SymbolTable.StringToId("DoWork"));
            Console.WriteLine("DoWork return value = {0}\n", rtnValue);

            // Perform a GetAttr on the object instance
            object attr = Ops.GetAttr((ICallerContext)pmodule, 
			pobj, SymbolTable.StringToId("attr"));
            Console.WriteLine("attr = {0}, type = {}\n", attr);

        }

Thanks in advance...

Mike

> -----Original Message-----
> From: users-bounces at lists.ironpython.com [mailto:users-
> bounces at lists.ironpython.com] On Behalf Of Dino Viehland
> Sent: Monday, January 15, 2007 11:46 AM
> To: Discussion of IronPython
> Subject: Re: [IronPython] Calling Python objects from C#?
> 
> I think the problem is that AllocateObject is equivalent to calling
> mytype.__new__ which is not quite what you want - you want the equivalent
> of doing mytype () or mytype.__call__()
> 
> I would change this to:
> 
>             // Get the Python Class from the module's global list
>             object ptype = module.Globals["MyClass"];
> 
>             // Create an instance of the object
>             object myclass = Ops.Call(ptype);
> 
> Not only is it more correct it gets rid of the direct dependency on
> UserType (for example your code wouldn't have worked w/ an old-style class
> or if a user had done MyClass = System.SomeTypeThatHasADoWorkMethod).
> 
> >From there I think your Ops.Invoke calls should work (although I haven't
> tried to make sure).
> 
> 
> -----Original Message-----
> From: users-bounces at lists.ironpython.com [mailto:users-
> bounces at lists.ironpython.com] On Behalf Of michael_sweeney at agilent.com
> Sent: Monday, January 15, 2007 9:58 AM
> To: users at lists.ironpython.com
> Subject: [IronPython] Calling Python objects from C#?
> 
> Hi All,
> 
> My apology if this has been asked before... I have searched for several
> examples and did not find what I was looking for.
> 
> My question is what is the best way to interact with Python objects from
> within C#? I need to call functions, capture the return value and get/set
> attributes from within C#.
> 
> I have tried several ways and ended up with this example for calling
> functions, but it generates an exception saying it does not know what
> "attr" is.
> 
> Here is my example:
> 
> File MyExample.py:
> 
> class MyClass(object):
>     def __init__(self):
>         self.attr = 500.0
> 
>     def DoWork(self):
>         print "Attr = ", self.attr
>         return self.attr
> 
> 
> File Program.cs:
> 
> using System;
> 
> using IronPython.Runtime;
> using IronPython.Runtime.Types;
> using IronPython.Runtime.Operations;
> using IronPython.Hosting;
> using IronPython.Modules;
> 
> namespace IPyExample
> {
>     class Program
>     {
>         static void Main(string[] args)
>         {
>             PythonEngine engine = new PythonEngine();
>             EngineModule module = engine.CreateModule("MyExample", true);
> 
>             try
>             {
>                 engine.ExecuteFile("MyExample.py", module);
>             }
>             catch (Exception ex)
>             {
>                 Console.WriteLine("Failed to execute Example.py file");
>                 Console.WriteLine("Exception: {0}", ex.Message);
>                 return;
>             }
> 
>             // Get the Python Class from the module's global list
>             UserType ptype = module.Globals["MyClass"] as UserType;
> 
>             // Create an instance of the object
>             object myclass = ptype.AllocateObject();
> 
>             // Call the method - Using Ops.Invoke()
>             Ops.Invoke(myclass, SymbolTable.StringToId("DoWork"));
> 
>             // Call the same method - Using UserType.Invoke()
>             object rtnValue = ptype.Invoke(myclass,
>                 SymbolTable.StringToId("DoWork"));
> 
>             Console.WriteLine("DoWork return value = {0}\n", rtnValue);
>         }
>     }
> }
> 
> 
> Exception:
> 
> C:\Documents and Settings\sweeneym\My Documents\Visual Studio
> 2005\Projects\ATF.
> IP\IPyExample\bin\Debug>IPYExample
> Attr =
> Unhandled Exception: System.MissingMemberException: attr
>    at IronPython.Runtime.Types.UserType.GetAttr(ICallerContext context,
> Object self, SymbolId name) in C:\Development\Ir
> onPython-1.1\Src\IronPython\Runtime\Types\UserType.cs:line 370
>    at IronPython.Runtime.Operations.Ops.GetAttr(ICallerContext context,
> Object o, SymbolId name) in C:\Development\IronP
> ython-1.1\Src\IronPython\Runtime\Operations\Ops.cs:line 1644
>    at DoWork$f1##4(FunctionEnvironment4Dictionary , Object )
>    at IronPython.Runtime.Calls.CallTarget1.Invoke(Object arg0)
>    at IronPython.Runtime.Calls.Function1.Call(ICallerContext context,
> Object arg0) in C:\Development\IronPython-1.1\Src\
> IronPython\Runtime\Calls\Function.Generated.cs:line 127
>    at IronPython.Runtime.Calls.Function1.Call(ICallerContext context,
> Object[] args) in C:\Development\IronPython-1.1\Sr
> c\IronPython\Runtime\Calls\Function.Generated.cs:line 138
>    at IronPython.Runtime.Calls.PythonFunction.CallInstance(ICallerContext
> context, Object instance, Object[] args) in C:
> \Development\IronPython-1.1\Src\IronPython\Runtime\Calls\Function.cs:line
> 389
>    at IronPython.Runtime.Calls.Method.Call(ICallerContext context,
> Object[] args) in C:\Development\IronPython-1.1\Src\I
> ronPython\Runtime\Calls\Function.cs:line 972
>    at IronPython.Runtime.Operations.Ops.Call(Object func, Object[] args)
> in C:\Development\IronPython-1.1\Src\IronPython
> \Runtime\Operations\Ops.cs:line 1414
>    at IronPython.Runtime.Types.DynamicType.Invoke(Object target, SymbolId
> name, Object[] args) in C:\Development\IronPyt
> hon-1.1\Src\IronPython\Runtime\Types\DynamicType.cs:line 1010
>    at IronPython.Runtime.Operations.Ops.Invoke(Object target, SymbolId
> name, Object[] args) in C:\Development\IronPython
> -1.1\Src\IronPython\Runtime\Operations\Ops.cs:line 1760
>    at IPyExample.Program.Main(String[] args) in C:\Documents and
> Settings\sweeneym\My Documents\Visual Studio 2005\Proje
> cts\ATF.IP\IPyExample\Program.cs:line 35
> 
> 
> ------------------------------------------------------------
> Michael A. Sweeney        email: michael_sweeney at agilent.com
> Agilent Technologies      phone: (509) 921-4395
> MS:3WU-222                fax:   (509) 921-3991
> 24001 E. Mission Ave.
> Liberty Lake, WA 99019 USA
> ------------------------------------------------------------
> 
> _______________________________________________
> users mailing list
> users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> _______________________________________________
> users mailing list
> users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



More information about the Ironpython-users mailing list