Введение
Интеграция скриптов Python в приложение на C# позволяет использовать обширные библиотеки Python, сохраняя при этом возможности C#. Этот гайд предоставляет пошаговое руководство по созданию приложения на C#, которое вызывает скрипт Python, использует виртуальное окружение для зависимостей Python и измеряет время выполнения скрипта.
Необходимые условия
-
Установлен .NET SDK
-
Установлен Python
-
Базовое понимание C# и Python
Шаг 1: Настройка окружения Python
-
Создайте виртуальное окружение: Откройте терминал или командную строку и перейдите в ваш проект.
python -m venv myenv -
Активируйте виртуальное окружение:
-
На Windows:
myenv\Scripts\activate -
На Unix или MacOS:
source myenv/bin/activate
-
-
Установите необходимые пакеты 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#
-
Создайте новое консольное приложение .NET:
dotnet new console -n CSharpPython cd CSharpPython -
Измените
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: Запуск приложения
-
Соберите приложение на C#:
dotnet build -
Запустите приложение:
dotnet run
Заключение
Следуя этим шагам, вы создадите приложение на C#, которое интегрируется со скриптом Python, используя виртуальное окружение для управления зависимостями Python. Этот подход гарантирует, что все необходимые библиотеки Python будут доступны, и позволяет надежно выполнять скрипт Python. Кроме того, вы реализовали измерение времени выполнения, чтобы отслеживать производительность скрипта Python.
ссылка на оригинал статьи https://habr.com/ru/articles/817041/
Добавить комментарий