From cefba0ede955c7af137841f1d54417125c667c35 Mon Sep 17 00:00:00 2001 From: jbw3 <> Date: Sat, 7 Jul 2018 18:17:05 -0500 Subject: [PATCH 1/2] Adding more C# examples --- README.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1415cc4..08b65b6 100644 --- a/README.md +++ b/README.md @@ -517,13 +517,74 @@ which may be called at startup without having acquired the GIL. When finished using Python APIs, managed code must call a corresponding `PythonEngine.ReleaseLock` to release the GIL and allow other threads -to use Python. +to use Python: + +```csharp +IntPtr gilState = PythonEngine.AcquireLock(); + +PythonEngine.Exec("doStuff()"); + +PythonEngine.ReleaseLock(gilState); +``` + +A `using` statement may also be used to acquire and release the GIL: + +```csharp +using (Py.GIL()) +{ + PythonEngine.Exec("doStuff()"); +} +``` The AcquireLock and ReleaseLock methods are thin wrappers over the unmanaged `PyGILState_Ensure` and `PyGILState_Release` functions from the Python API, and the documentation for those APIs applies to the managed versions. +## Passing C# Objects to the Python Engine + +This section demonstrates how to pass a C# object to the Python runtime. +The example uses the following `Person` class: + +```csharp +public class Person +{ + public Person(string firstName, string lastName) + { + FirstName = firstName; + LastName = lastName; + } + + public string FirstName { get; set; } + public string LastName { get; set; } +} +``` + +In order to pass a C# object to the Python runtime, it must be converted to a +`PyObject`. This is done using the `ToPython` extension method. The `PyObject` +may then be added to a dictionary of local variables and passed to the +`PythonEngine.Exec` function: + +```csharp +// create a person object +Person person = new Person("John", "Smith"); + +// acquire the GIL before using the Python interpreter +using (Py.GIL()) +{ + // convert the Person object to a PyObject + PyObject pyPerson = person.ToPython(); + + // create a Python variable "person" + PyDict locals = new PyDict(); + locals["person"] = pyPerson; + + // the person object may now be used in Python + string code = "fullName = person.FirstName + ' ' + person.LastName"; + PythonEngine.Exec(code, null, locals.Handle); +} +``` + ## License Python for .NET is released under the open source MIT License. From c7c7379674abc19b02cb14a751aa54e932d018db Mon Sep 17 00:00:00 2001 From: jbw3 <> Date: Mon, 20 Aug 2018 20:49:30 -0500 Subject: [PATCH 2/2] Addressing code review comments --- README.md | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 08b65b6..23b5103 100644 --- a/README.md +++ b/README.md @@ -517,17 +517,9 @@ which may be called at startup without having acquired the GIL. When finished using Python APIs, managed code must call a corresponding `PythonEngine.ReleaseLock` to release the GIL and allow other threads -to use Python: +to use Python. -```csharp -IntPtr gilState = PythonEngine.AcquireLock(); - -PythonEngine.Exec("doStuff()"); - -PythonEngine.ReleaseLock(gilState); -``` - -A `using` statement may also be used to acquire and release the GIL: +A `using` statement may be used to acquire and release the GIL: ```csharp using (Py.GIL()) @@ -561,9 +553,9 @@ public class Person ``` In order to pass a C# object to the Python runtime, it must be converted to a -`PyObject`. This is done using the `ToPython` extension method. The `PyObject` -may then be added to a dictionary of local variables and passed to the -`PythonEngine.Exec` function: +`PyObject`. This is done using the `ToPython()` extension method. The `PyObject` +may then be set as a variable in a `PyScope`. Code executed from the scope +will have access to the variable: ```csharp // create a person object @@ -572,16 +564,19 @@ Person person = new Person("John", "Smith"); // acquire the GIL before using the Python interpreter using (Py.GIL()) { - // convert the Person object to a PyObject - PyObject pyPerson = person.ToPython(); + // create a Python scope + using (PyScope scope = Py.CreateScope()) + { + // convert the Person object to a PyObject + PyObject pyPerson = person.ToPython(); - // create a Python variable "person" - PyDict locals = new PyDict(); - locals["person"] = pyPerson; + // create a Python variable "person" + scope.Set("person", pyPerson); - // the person object may now be used in Python - string code = "fullName = person.FirstName + ' ' + person.LastName"; - PythonEngine.Exec(code, null, locals.Handle); + // the person object may now be used in Python + string code = "fullName = person.FirstName + ' ' + person.LastName"; + scope.Exec(code); + } } ```