Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Close the Python.NET script engine
#1
The following code, using the Python.NET component to execute a Python script, can be executed successfully.
However, the script engine is not closed. Here is a demonstration of the operation.

[Image: close.gif]
Where should this line of code be placed? I'm stuck! Shy
PythonEngine.Shutdown(); 

Thanks in advance for any suggestions and help.
 
Code:
Copy      Help
// script "PythonNET_Test.cs"
/*/ r %dll%\PyNet\Python.Runtime.dll /*/

using System;
using Python.Runtime;

class Program
{
    public static void Main()
    {

        Person someone = new Person();
        someone.FirstName = "John";
        someone.LastName = "Doe";
        someone.Age = 21;
        object age = PythonInterop.RunPythonCodeAndReturn(@"
someone.Age=someone.Age+3;
hisAge=someone.Age
"
, someone, "someone", "hisAge");
        Console.WriteLine("His age has changed to: " + age.ToString());
    }


    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }

    
    public class PythonInterop
    {
        public static void Initialize()
        {

            string pythonDll = @"C:\Users\YourUserNameHere\AppData\Local\Programs\Python\Python38\python38.dll";
            Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", pythonDll);
            
            PythonEngine.Initialize();
        }

        
        public static object RunPythonCodeAndReturn(string pycode, object parameter, string parameterName, string returnedVariableName)
        {

            object returnedVariable = new object(); 
            Initialize(); 
            using (Py.GIL()) 
            {

                using (var scope = Py.CreateScope()) 
                {

                    scope.Set(parameterName, parameter.ToPython());
                    scope.Exec(pycode);

                    returnedVariable = scope.Get<object>(returnedVariableName); 
                    return returnedVariable;
                }
            }

            PythonEngine.Shutdown(); 
        }
    }
}
#2
Use try-finally. Or class Pynet from https://www.libreautomate.com/forum/show...p?tid=7484
#3
pythonnet engine is an invisible process. I execute #1 C# code in QM. The first execution is successful. However, the macro fails to terminate in the second execution, leading to QM crashing. Sad

By using the Pynet class in the link below, the engine can exit properly. However, I am not sure how to add the following function to that class.
https://www.libreautomate.com/forum/show...5#pid36975
Quote:public static object RunPythonCodeAndReturn(string pycode, object parameter, string parameterName, string returnedVariableName)
        {
            try
            {
                object returnedVariable = new object();
                Initialize();
                using (Py.GIL())
                {
                    using (var scope = Py.CreateScope())
                    {
                        scope.Set(parameterName, parameter.ToPython());
                        scope.Exec(pycode);
                        
                        returnedVariable = scope.Get<object>(returnedVariableName);
                        return returnedVariable;
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

Another code! It would be fantastic if it could be added to the Pynet class.
Code:
Copy      Help
public dynamic? ExecuteScript<T>(string scriptFile, string className, string functionName, List<object> paramset)
{
    T? result = default;
    try
    {
        // Location of all the python scripts in the project. lets get the python file we are specifying in the function param
        string file = $"{Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)}\\PythonScripts\\{scriptFile}.py";

        // This is initalized in the program.cs, but just want to make sure it's initialized in case something happens
        if (!PythonEngine.IsInitialized)
        {
            PythonEngine.Initialize();
            Py.GIL();
        }

        using (var scope = Py.CreateScope())
        {
            // Our returned PythonObject from the python function call
            PyObject? pythonReturn;
            // Get the python file as raw text
            string code = File.ReadAllText(file);
            // Compile the code/file
            var scriptCompiled = PythonEngine.Compile(code, file);
            // Execute the compiled python so we can start calling it
            scope.Execute(scriptCompiled);

            // Lets get an instance of the class in python
            PyObject pythonClass = scope.Get(className);

            // Add parameters to the function?
            if (paramset != null && paramset.Count > 0)
            {
                // This is an array of python parameters passed into a function
                PyObject[] pyParams = new PyObject[paramset.Count];

                // Loop through our incoming c# list of parameters and create PythonObject array .
                for (int i = 0; i < paramset.Count; i++)
                {
                    pyParams[i] = paramset[i].ToPython();
                }
                // Call the  function on the class with parameters
                pythonReturn = pythonClass.InvokeMethod(functionName, pyParams);
            }
            else // We aren't using parameters here
                 // Call the  function on the class
                pythonReturn = pythonClass.InvokeMethod(functionName);

            // Lets convert our returned pythonObject to that of the object type (C#)
            object? netObject = pythonReturn.AsManagedObject(typeof(object));

            // A special case of when we want a list back. We will convert the object to the specific type in the caller function
            if (typeof(T) == typeof(IList<object>))
            {
                object[] something = pythonReturn.As<object[]>();
                return something;
            }

            // Convert the c# object to that of what we expect to be returned,. string/int/bool/class
            if (netObject != null)
                // convert the returned string to managed string object
                result = (T)netObject;
        }
        return result;
    }
    catch (Exception)
    {
        // Handle your exceptions here
        throw;
    }
}


Forum Jump:


Users browsing this thread: 3 Guest(s)