[IronPython] Extension methods in python

Dino Viehland dinov at microsoft.com
Fri Nov 7 05:26:08 CET 2008


Ok, you don’t want extension methods, you want a dynamic object, and the good and bad news is there are a few options ☺

Let's start with the "correct" options first.  If you can change the base class the easiest thing to do would be to subclass Microsoft.Scripting.Actions.Dynamic.  Then you can override GetMember and return another subclass of Dynamic which overrides SetMember and enables .Bar = value to work.

If you can’t change the subclass then you need to implement IDynamicObject.  There’s only one method to implement and all it does is return a new MetaObject.  That MetaObject is a subclass of MetaObject that you define for your type and it can then override methods like GetMember or SetMember (there's many more) and instead of returning the values it returns a new MetaObject.  It’s hard to give you exact sample code because I don’t know if PropertySet is an indexed property defined in VB, or if it returns a Dictionary<string, ??>, etc…  But in general you just want to look at the Expression class and use its factories - and if you're familiar with .NET reflection you might find it straight forward.  But the general idea is you'll want to do something like:

            return new MetaObject(
                Expression.Call(
                    Expression.Property(Expression, Value.GetType().GetProperty("PropertySet")),
                    typeof(Dictionary<string, Dictionary<string, object>>).GetMethod("get_Item"),
                    Expression.Constant(action.Name)
                ),
                Restrictions.TypeRestriction(Expression, Value.GetType())
            );

And something similar for SetMember exception for you'll have an extra MetaObject coming in as value there, so you'd end up with something similar like:

            return new MetaObject(
                Expression.AssignProperty(
                    Expression.Call(Expression, Value.GetType().GetMethod("get_Item")),
                    typeof(Whatever).GetProperty("Value"),
                    value.Expression
                ),
                Restrictions.TypeRestriction(Expression, Value.GetType())
            );

The non-correct way (long-term) is that you can make it work with IronPython but not necessarily other languages (e.g. C# dynamic) but the flip side is it's really easy and straight forward.  There you can define a couple of methods like this:

        [SpecialName]
        public object GetCustomMember(string name) {
          return row.PropertySet[name];
      }


And in whatever type row.PropertySet["Foo"] returns:

        [SpecialName]
        public void SetMember(string name, object value) {
                this[name] = value;
      }




From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Marty Nelson
Sent: Thursday, November 06, 2008 8:02 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Extension methods in python

Like a Christmas tree.

________________________________________
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Dino Viehland
Sent: Thursday, November 06, 2008 7:20 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Extension methods in python

By custom class you mean a class you’ve written?  And then you want it to “light up” with dynamic languages?

From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Marty Nelson
Sent: Thursday, November 06, 2008 7:18 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Extension methods in python

I actually want to use an object instance of a .NET custom class that I pass in before the script is invoked from c#.  Our current scripts look something like:

row.PropertySet[“Foo”][“Bar”].Value = x

and it would be much better if script authors could write:

row.Foo.Bar = x

So I’m looking to have an on the fly function read the metadata of expected keys and then code generated python class wrapper for the script author to consume.

________________________________________
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Miha Valencic
Sent: Thursday, November 06, 2008 9:08 AM
To: Discussion of IronPython
Subject: Re: [IronPython] Extension methods in python

Marty, from what I understand you are passing a variable into python engine and want extension methods there? You can use something like that:

import clr
import System

class MyString(System.String):
  pass;

  def ToFoo(self):
    return self.upper()+' FooBarBaz'


a = MyString("Hello world!");
print a.ToFoo();



That would print "HELLO WORLD! FooBarBaz.

You can't put methods on System.String though, but you can create new object from System.String...

Miha
2008/11/5 Marty Nelson <Marty.Nelson at symyx.com>
Is there the equivalent of extension method in python?  I want to put a variable into the script scope and create extension methods for it.  Does this make sense and is it possible?

=======
Notice: This e-mail message, together with any attachments, contains
information of Symyx Technologies, Inc. or any of its affiliates or
subsidiaries that may be confidential, proprietary, copyrighted,
privileged and/or protected work product, and is meant solely for
the intended recipient. If you are not the intended recipient, and
have received this message in error, please contact the sender
immediately, permanently delete the original and any copies of this
email and any attachments thereto.



More information about the Ironpython-users mailing list