Как создать приложение на C# с использованием приложения на Python

от автора

Введение

Интеграция скриптов Python в приложение на C# позволяет использовать обширные библиотеки Python, сохраняя при этом возможности C#. Этот гайд предоставляет пошаговое руководство по созданию приложения на C#, которое вызывает скрипт Python, использует виртуальное окружение для зависимостей Python и измеряет время выполнения скрипта.

Необходимые условия

  • Установлен .NET SDK

  • Установлен Python

  • Базовое понимание C# и Python

Шаг 1: Настройка окружения Python

  1. Создайте виртуальное окружение: Откройте терминал или командную строку и перейдите в ваш проект.

    python -m venv myenv
  2. Активируйте виртуальное окружение:

    • На Windows:

      myenv\Scripts\activate
    • На Unix или MacOS:

      source myenv/bin/activate
  3. Установите необходимые пакеты Python:

    pip install pandas

Шаг 2: Создание скрипта Python

Создайте скрипт Python, который выполняет простую задачу с использованием pandas. Сохраните этот скрипт как main.py в директории PythonApplication.

import sys import pandas as pd  def add(a, b):     return a + b  if __name__ == "__main__":     if len(sys.argv) != 3:         print("Usage: python main.py <num1> <num2>")         sys.exit(1)      # Создание DataFrame с входными числами     data = {'num1': [sys.argv[1]], 'num2': [sys.argv[2]]}     df = pd.DataFrame(data)      # Преобразование колонок в тип float     df = df.astype(float)      # Выполнение сложения     result = add(df['num1'].iloc[0], df['num2'].iloc[0])          print(result) 

Шаг 3: Создание приложения на C#

  1. Создайте новое консольное приложение .NET:

    dotnet new console -n CSharpPython cd CSharpPython
  2. Измените Program.cs для выполнения скрипта Python:
    Замените содержимое Program.cs следующим кодом:

using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Globalization;  class Program {     static void Main(string[] args)     {         try         {             // Получение относительного пути к скрипту Python             string pythonScriptPath = FindPythonScript("PythonApplication", "main.py");              // Проверка наличия скрипта Python             if (string.IsNullOrEmpty(pythonScriptPath) || !File.Exists(pythonScriptPath))             {                 Console.WriteLine($"Ошибка: скрипт Python не найден по пути: {pythonScriptPath}");                 return;             }              // Путь к интерпретатору Python в виртуальном окружении             string pythonInterpreterPath = FindPythonInterpreter("PythonApplication", "myenv", "Scripts", "python.exe");              // Проверка наличия интерпретатора Python             if (string.IsNullOrEmpty(pythonInterpreterPath) || !File.Exists(pythonInterpreterPath))             {                 Console.WriteLine($"Ошибка: интерпретатор Python не найден по пути: {pythonInterpreterPath}");                 return;             }              // Числа для сложения             double num1 = 5.5;             double num2 = 4.5;              // Преобразование чисел в строки с использованием invariant culture (точка как десятичный разделитель)             string num1Str = num1.ToString(CultureInfo.InvariantCulture);             string num2Str = num2.ToString(CultureInfo.InvariantCulture);              // Начало измерения времени выполнения             Stopwatch stopwatch = new Stopwatch();             stopwatch.Start();              // Настройка процесса для вызова скрипта Python             ProcessStartInfo start = new ProcessStartInfo();             start.FileName = pythonInterpreterPath;             start.Arguments = $"{pythonScriptPath} {num1Str} {num2Str}";             start.WorkingDirectory = Path.GetDirectoryName(pythonScriptPath);             start.UseShellExecute = false;             start.RedirectStandardOutput = true;             start.RedirectStandardError = true; // Захват стандартного вывода ошибок             start.CreateNoWindow = true;              using (Process process = Process.Start(start))             {                 using (StreamReader reader = process.StandardOutput)                 {                     string result = reader.ReadToEnd();                     Console.WriteLine($"Результат: {result}");                 }                  using (StreamReader errorReader = process.StandardError)                 {                     string error = errorReader.ReadToEnd();                     if (!string.IsNullOrEmpty(error))                     {                         Console.WriteLine($"Ошибка: {error}");                     }                 }                  process.WaitForExit();                 int exitCode = process.ExitCode;                 Console.WriteLine($"Процесс завершился с кодом: {exitCode}");             }              // Остановка измерения времени выполнения             stopwatch.Stop();             TimeSpan ts = stopwatch.Elapsed;             Console.WriteLine($"Время выполнения: {ts.TotalMilliseconds} мс");         }         catch (Exception ex)         {             Console.WriteLine($"Исключение: {ex.Message}");             Console.WriteLine($"Стек вызовов: {ex.StackTrace}");         }     }      static string FindPythonScript(string directory, string scriptName)     {         return FindFile(directory, scriptName);     }      static string FindPythonInterpreter(string directory, string venvDirectory, string scriptsDirectory, string pythonExe)     {         return FindFile(directory, Path.Combine(venvDirectory, scriptsDirectory, pythonExe));     }      static string FindFile(string directory, string fileName)     {         // Получение начального каталога сборки         string currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);          while (currentDirectory != null)         {             string foundPath = SearchDirectory(currentDirectory, directory, fileName);             if (foundPath != null)             {                 return foundPath;             }              // Переход в родительский каталог             currentDirectory = Directory.GetParent(currentDirectory)?.FullName;         }          // Если файл не найден, вернуть null         return null;     }      static string SearchDirectory(string baseDirectory, string targetDirectory, string fileName)     {         // Получение полного пути к целевой директории         string targetPath = Path.Combine(baseDirectory, targetDirectory);          if (Directory.Exists(targetPath))         {             string filePath = Path.Combine(targetPath, fileName);             if (File.Exists(filePath))             {                 return filePath;             }              // Рекурсивный поиск в подкаталогах             foreach (string subDirectory in Directory.GetDirectories(targetPath))             {                 string foundPath = SearchDirectory(subDirectory, string.Empty, fileName);                 if (foundPath != null)                 {                     return foundPath;                 }             }         }          return null;     } } 

Шаг 4: Запуск приложения

  1. Соберите приложение на C#:

    dotnet build
  2. Запустите приложение:

    dotnet run

Заключение

Следуя этим шагам, вы создадите приложение на C#, которое интегрируется со скриптом Python, используя виртуальное окружение для управления зависимостями Python. Этот подход гарантирует, что все необходимые библиотеки Python будут доступны, и позволяет надежно выполнять скрипт Python. Кроме того, вы реализовали измерение времени выполнения, чтобы отслеживать производительность скрипта Python.


ссылка на оригинал статьи https://habr.com/ru/articles/817041/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *