[IronPython] Calling Python objects from C#?

Dino Viehland dinov at exchange.microsoft.com
Mon Jan 15 22:07:56 CET 2007


For the context you should be able to use DefaultContext.Default.  If you wanted members from .NET types to show up on types that are used natively in Python (e.g. string, int, etc...) you could use DefaultContext.DefaultCLS.  If you wanted the lookup to reflect what had happened in the module (e.g. whether the user has done import clr or import <some .NET namespace>) then you'd want to pass the module instance as the context.



-----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 12:55 PM
To: users at lists.ironpython.com
Subject: Re: [IronPython] Calling Python objects from C#?

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
_______________________________________________
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