Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Introduction to Python.Net

2,359 views

Published on

Short introduction to Python.NET at the .NET User Group in Paderborn. Displays history programming constructs and architecture.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Introduction to Python.Net

  1. 1. INTRODUCTION TO PYTHON.NET
  2. 2. ABOUT ME • Stefan Schukat • Software Architect, Physicist • Different programming stages over the last 30 years • Pascal, TCL/TK • C/C++, ATL/MFC, COM, (VB) • Python • M • C# • Interest in software forensic and cross language techniques • Twitter @tschodila • https://www.xing.com/profile/Stefan_Schukat2
  3. 3. WHY CONSIDER PYTHON?
  4. 4. BASE OF PYTHON • High level interpreted language • Dynamic execution with no static typing • Only few basic data types and programming elements are defined • Interpreter engine could be implemented on different languages • Extendable and embeddable
  5. 5. BASE PYTHON EXECUTION ARCHITECTURE Python Code Byte Code Python API Parse Interpreter Use Extension modul Call Native API Call Call C : C-Python C# : IronPython Java : Jython Python : PyPy
  6. 6. PYTHON .NET • Python Extension module for C-Python • Access .NET runtime and libraries from Python scripting • Combines history and amount of extensions from C-Python with .NET • Allows scripting access to .NET libraries in C-Python • Allows embedding in console .NET Application to use C-Python in .NET • https://github.com/pythonnet/pythonnet
  7. 7. PYTHON.NET HISTORY • Developer Brian Lloyd, Barton Cline, Christian Heimes • Goal integrate .NET seamlessly in Python on Mono and Windows • 1.0 for .NET 1.0 (2005), .NET 2.0 (2006) • 2.0 Beta .NET 4.0 (2013) project abandoned • Revived 2014 on GitHub • Denis Akhiyarov, David Anthoff, Tony Roberts, Victor Uriarte • 2.1 for .NET 4.x, Python 2.x, 3.x (2016) • 2.2 for .NET 4.x, Added Python 3.6 (2017) • .NET Core support is planned
  8. 8. PYTHON.NET ARCHITECTURE clr.pyd .NET Assembly Dynam ic Load PyInit_Clr Python.Runtime. dll .NET Assembly C-Export for Python Dll Import Python C-API Wrapper Objects for Python Type APIs Import Hook Type Conversions Reflection …
  9. 9. PYTHON.NET RUNTIME OVERVIEW DllImport("python.dll", …) DllImport("python.dll", …) … Runtime InitExt(…) Engine PySequence PyDict ModuleObject ClassObject PropertyObject … Class Wrapper for .NET Types P-Invoke Wrapper for C- API Class Wrapper for Python Types … Main entry point Entry from Python Translation Python/NET Access Python-API
  10. 10. PYTHON .NET BASICS • Uses reflection to initialize Python wrappers from .NET objects • All public and protected members are available • In case of name clash static method are preferred over instance methods • Maps .NET namespaces to Python modules via Python import hook • Import statement prefers Python modules over .NET modules • All variables in Python are reference types • Any value type is always boxed in Python.NET • Default mapping of data types between Python and BCL
  11. 11. TYPES MAPPING .NET Type Python Type String, Char unicode Int16, UInt16, Int32, UInt32, Byte, SByte int Int64, UInt64, UInt32 long (Py 2.x), int (Py 3.x) Boolean bool Single, Double float IEnumerable list (sequence protocol) null None Decimal object Struct decimal
  12. 12. ACCESSING NAMESPACE / ASSEMBLIES >>> import clr # Initialize Runtime >>> from System import String # Import Class from namespace >>> from System.Collections import * # Import all from subnamespace >>> clr.AddReference("System.Windows.Forms") # Add assembly <System.Reflection.RuntimeAssembly object at 0x0000020A5FF06CF8> >>> import System.Windows.Forms >>> clr.AddReference("customsigned, Version=1.5.0.0, Culture=neutral, PublicKeyToken=12345678babeaffe") • Search order • Standard Python modules • Loaded Assemblies • Python path for .NET assemblies (Assembly.LoadFrom) • .NET Loader (Assembly.Load)
  13. 13. STRUCTS, METHODS, PROPERTIES >>> import System.Drawing import Point # Import struct >>> p = Point(5, 5) # Instantiate struct >>> p.X # Access property 5 >>> from System import Math # Import static class >>> Math.Abs(-212) # Access Method 212
  14. 14. GENERICS AND OVERLOADS >>> from System import String, Char, Int32 # Import used types >>> s = String.Overloads[Char, Int32]("A", 10) # Use overloaded constructor >>> s # display class <System.String object at 0x0000020A5FF64908> >>> print(s) # Use ToString method AAAAAAAA >>> from System.Collections.Generic import Dictionary # Import used types >>> d = Dictionary[String, String]() # Use generic constructor >>> d2 = Dictionary[str, str]() # Use auto mapped types >>> print(d) # Use ToString method System.Collections.Generic.Dictionary`2[System.String,System.String]
  15. 15. INDEXERS, ARRAYS >>> from System.Collections.Generic import Dictionary as d >>> jagged = d[str, d[str, int]]() # Create dict of dicts >>> jagged["a"] = d[str, int]() >>> jagged["a"]["b"] = 10 >>> jagged["a"]["b"] 10 >>> from System import Array >>> a = Array[int]([2,2]) >>> a <System.Int32[] object at 0x0000020A5FF838D0> >>> a[0] # Multidimensional a[1,1] 2
  16. 16. DELEGATES AND EVENTS >>> from System import AssemblyLoadEventHandler, AppDomain >>> def LoadHandler(source, args): ... print("Python called for {0}".format(args.LoadAssembly.FullName)) ... >>> e = AssemblyLoadEventHandler(LoadHandler) # Create delegate >>> AppDomain.CurrentDomain.AssemblyLoad += e # Register delegate >>> clr.AddReference("System.Windows.Forms") # Add assembly Python called for Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Python called for System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Python called for System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a >>> AppDomain.CurrentDomain.AssemblyLoad -= e # Unregister delegate
  17. 17. EXCEPTIONS >>> from System import NullReferenceException # Use BCL exception >>> try: ... raise NullReferenceException("Empty test") ... except NullReferenceException as e: ... print(e.Message) ... print(e.Source) Empty test None
  18. 18. COLLECTIONS >>> from System import AppDomain # Use class which supports IEnumerable >>> for item in AppDomain.CurrentDomain.GetAssemblies(): ... print(item.FullName) ... mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 clrmodule, Version=2.3.0.0, Culture=neutral, PublicKeyToken=null Python.Runtime, Version=2.4.0.0, Culture=neutral, PublicKeyToken=null System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 __CodeGenerator_Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null e__NativeCall_Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a …
  19. 19. UI PYTHON .NET • Simple way • Write .NET Class Assembly with UI (Winforms or WPF) • Export functions to be used • Hard way • Rewrite generated code via Python.NET
  20. 20. UI WINFORMS C# CODE using System; using System.Windows.Forms; namespace UILibrary { public partial class MainForm : Form { public Action PythonCallBack { get; set; } public MainForm() { InitializeComponent(); } private void ButtonCallPython_Click(object sender, System.EventArgs e) => this.PythonCallBack?.Invoke(); } }
  21. 21. UI WINFORMS PYTHON CODE IN UI APPLICATIONimport clr clr.AddReference("UILibrary") import UILibrary from System import Action def CallBack(): """Button click event handler""" print("Button clicked!") MainForm = UILibrary.MainForm() MainForm.PythonCallBack = Action(CallBack) MainForm.ShowDialog()
  22. 22. UI WINFORMS PYTHON CODE IN CONSOLE APPimport clr clr.AddReference("System.Windows.Forms") clr.AddReference("UILibrary") import System.Windows.Forms as WinForms import UILibrary from System import Action class WinFormsTest: def __init__(self): self.MainForm = UILibrary.MainForm() self.MainForm.PythonCallBack = Action(self.CallBack) app = WinForms.Application app.Run(self.MainForm) def CallBack(self): """Button click event handler""" print("Button clicked!") if __name__ == '__main__': ui = WinFormsTest()
  23. 23. WINFORMS PURE PYTHON self.buttonCallPython.Click += System.EventHandler(self.ButtonCallPython_Click) self.AutoScaleDimensions = System.Drawing.SizeF(6.0, 13.0) self.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font self.ClientSize = System.Drawing.Size(245, 44) self.Controls.Add(self.buttonCallPython) self.MaximizeBox = False self.MinimizeBox = False self.Name = "MainForm" self.Text = "TestWinforms" self.ResumeLayout(False) if __name__ == "__main__": m = MainForm() m.ShowDialog() import clr import System import System.Windows.Forms import System.Drawing class MainForm(System.Windows.Forms.Form): def __init__(self): self.InitializeComponent() def ButtonCallPython_Click(self, source, args): print("Button clicked") def InitializeComponent(self): self.buttonCallPython = System.Windows.Forms.Button() self.SuspendLayout() self.buttonCallPython.Location = System.Drawing.Point(12, 12) self.buttonCallPython.Name = "buttonCallPython" self.buttonCallPython.Size = System.Drawing.Size(75, 23) self.buttonCallPython.TabIndex = 0 self.buttonCallPython.Text = "Call Python" self.buttonCallPython.UseVisualStyleBackColor = True
  24. 24. FURTHER USE CASES • Automatic conversion of Python dictionary as .NET dictionary • Usage of .NET enums as Python enums • Routing of win32com.client COM objects as __ComObject
  25. 25. THANK YOU! ???????

×