ncosentino

Dynamically Modify a Python Class Within C#

Sep 29th, 2013
309
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // -------------------------------------------------------------------------------------
  2. // This is an example from a blog post over at Dev Leader. Check it out:
  3. // http://www.devleader.ca/2013/10/01/dynamic-python-c/
  4. //
  5. // Follow Dev Leader:
  6. // Facebook - http://www.facebook.com/DevLeaderCa
  7. // Google+ - https://plus.google.com/b/108985236662325804542/108985236662325804542/posts
  8. // Twitter - http://www.twitter.com/nbcosentino
  9. // -------------------------------------------------------------------------------------
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Text;
  13.  
  14. using Microsoft.CSharp.RuntimeBinder;
  15.  
  16. using IronPython.Hosting;
  17.  
  18. namespace DynamicClass
  19. {
  20.     internal class Program
  21.     {
  22.         private static void Main(string[] args)
  23.         {
  24.             Console.WriteLine("Press enter to read the value of 'MyProperty' from a Python object before we actually add the dynamic property.");
  25.             Console.ReadLine();
  26.  
  27.             // this script was taken from this blog post:
  28.             // http://znasibov.info/blog/html/2010/03/10/python-classes-dynamic-properties.html
  29.             var script =
  30.                 "class Properties(object):\r\n" +
  31.                 "    def add_property(self, name, value):\r\n" +
  32.                 "        # create local fget and fset functions\r\n" +
  33.                 "        fget = lambda self: self._get_property(name)\r\n" +
  34.                 "        fset = lambda self, value: self._set_property(name, value)\r\n" +
  35.                 "\r\n" +
  36.                 "        # add property to self\r\n" +
  37.                 "        setattr(self.__class__, name, property(fget, fset))\r\n" +
  38.                 "        # add corresponding local variable\r\n" +
  39.                 "        setattr(self, '_' + name, value)\r\n" +
  40.                 "\r\n" +
  41.                 "\r\n" +
  42.                 "    def _set_property(self, name, value):\r\n" +
  43.                 "        setattr(self, '_' + name, value)\r\n" +
  44.                 "\r\n" +
  45.                 "    def _get_property(self, name):\r\n" +
  46.                 "        return getattr(self, '_' + name)\r\n";
  47.  
  48.             try
  49.             {
  50.                 var engine = Python.CreateEngine();
  51.                 var scope = engine.CreateScope();
  52.                 var ops = engine.Operations;
  53.  
  54.                 engine.Execute(script, scope);
  55.                 var pythonType = scope.GetVariable("Properties");
  56.                 dynamic instance = ops.CreateInstance(pythonType);
  57.  
  58.                 try
  59.                 {
  60.                     Console.WriteLine(instance.MyProperty);
  61.                     throw new InvalidOperationException("This class doesn't have the property we want, so this should be impossible!");
  62.                 }
  63.                 catch (RuntimeBinderException)
  64.                 {
  65.                     Console.WriteLine("We got the exception as expected!");
  66.                 }
  67.  
  68.                 Console.WriteLine();
  69.                 Console.WriteLine("Press enter to add the property 'MyProperty' to our Python object and then try to read the value.");
  70.                 Console.ReadLine();
  71.  
  72.                 instance.add_property("MyProperty", "Expected value of MyProperty!");
  73.                 Console.WriteLine(instance.MyProperty);
  74.             }
  75.             catch (Exception ex)
  76.             {
  77.                 Console.WriteLine("Oops! There was an exception while running the script: " + ex.Message);
  78.             }
  79.  
  80.             Console.WriteLine("Press enter to exit...");
  81.             Console.ReadLine();
  82.         }
  83.     }
  84. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×