У меня есть очень простое приложение C#, использующее Python.net 3.0.3 в net8.0, которое пытается вызвать модуль Python в каталоге bin/Debug/net8.0, который возвращает произведение двух чисел. В Windows это работает, в Ubuntu я получаю Python.Runtime.PythonException с сообщением No module named 'script'. Файлы на обеих машинах одинаковые.
Код:
namespace PythonLoader
{
using System;
using System.Runtime.InteropServices;
using GetSomeInput;
using Python.Runtime;
public class Program
{
public static void Main(string[] args)
{
try
{
string script = Inputty.GetString("Module name: ", "script", false);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Runtime.PythonDLL = @"C:\Python312\python312.dll";
}
else
{
// see https://stackoverflow.com/questions/20582270/distribution-independent-libpython-path
Runtime.PythonDLL = @"/usr/lib/x86_64-linux-gnu/libpython3.10.so";
}
PythonEngine.Initialize();
PythonEngine.BeginAllowThreads();
Console.WriteLine("Using Python DLL : " + Runtime.PythonDLL);
Console.WriteLine("Using Python version : " + PythonEngine.Version);
Console.WriteLine("Build information : " + PythonEngine.BuildInfo);
Console.WriteLine("Compiler : " + PythonEngine.Compiler);
Console.WriteLine("Max supported version : " + PythonEngine.MaxSupportedVersion);
Console.WriteLine("Min supported version : " + PythonEngine.MinSupportedVersion);
Console.WriteLine("Platform : " + PythonEngine.Platform);
Console.WriteLine("Program name : " + PythonEngine.ProgramName);
Console.WriteLine("Python home : " + PythonEngine.PythonHome);
Console.WriteLine("Python path : " + PythonEngine.PythonPath);
using (Py.GIL())
{
dynamic app = Py.Import(script);
Console.WriteLine(app.multiply(2, 4));
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
Файл script.py
def multiply(a, b):
return a * b
Файл __init__.py
from script import multiply
Оба этих файла копируются в выходной каталог (например, bin/Debug/net8.0.
Работает в Windows:
C:\Code\Misc\PythonLoader\PythonLoader\bin\Debug\net8.0>pythonloader
Module name: [script]
Using Python DLL : C:\Python312\python312.dll
Using Python version : 3.12.2 (tags/v3.12.2:6abddd9, Feb 6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)]
Build information : tags/v3.12.2:6abddd9, Feb 6 2024, 21:26:36
Compiler : [MSC v.1937 64 bit (AMD64)]
Max supported version : 3.12.2147483647.2147483647
Min supported version : 3.7
Platform : win32
Program name : python
Python home :
Python path : C:\Python312\python312.zip;C:\Python312\DLLs;C:\Python312\Lib;C:\Code\Misc\PythonLoader\PythonLoader\bin\Debug\net8.0
8
Не работает в Ubuntu:
joel@ubuntu:~/Code/pythontest/bin/Debug/net8.0$ ./pythontest
Python filename: [script.py]
Using Python DLL : /usr/lib/x86_64-linux-gnu/libpython3.10.so
Using Python version : 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
Build information : main, Nov 20 2023, 15:14:05
Compiler : [GCC 11.4.0]
Max supported version : 3.12.2147483647.2147483647
Min supported version : 3.7
Platform : linux
Program name : python3
Python home :
Python path : /usr/lib/python310.zip:/usr/lib/python3.10:/usr/lib/python3.10/lib-dynload:/home/joel/Code/pythontest/bin/Debug/net8.0
Python.Runtime.PythonException: No module named 'script'
at Python.Runtime.PythonException.ThrowLastAsClrException()
at Python.Runtime.NewReferenceExtensions.BorrowOrThrow(NewReference& reference)
at Python.Runtime.PyModule.Import(String name)
at Python.Runtime.Py.Import(String name)
at PythonLoader.Program.Main(String[] args) in /home/joel/Code/pythontest/Program.cs:line 59
Содержимое каталога в Windows:
C:\Code\Misc\PythonLoader\PythonLoader\bin\Debug\net8.0>dir
Volume in drive C is OS
Volume Serial Number is 541C-D54E
Directory of C:\Code\Misc\PythonLoader\PythonLoader\bin\Debug\net8.0
05/24/2024 08:34 PM <DIR> .
05/24/2024 09:07 AM <DIR> ..
01/11/2024 11:37 AM 322,048 GetSomeInput.dll
10/11/2023 12:15 AM 431,616 Python.Runtime.dll
05/24/2024 02:32 PM 7,378 PythonLoader.deps.json
05/24/2024 08:34 PM 6,656 PythonLoader.dll
05/24/2024 08:34 PM 142,848 PythonLoader.exe
05/24/2024 08:34 PM 10,932 PythonLoader.pdb
05/24/2024 09:17 AM 268 PythonLoader.runtimeconfig.json
05/24/2024 09:16 AM 37 script.py
05/24/2024 03:40 PM 29 __init__.py
05/24/2024 09:21 AM <DIR> __pycache__
9 File(s) 921,812 bytes
3 Dir(s) 48,029,245,440 bytes free
Содержимое каталога в Ubuntu:
joel@ubuntu:~/Code/pythontest/bin/Debug/net8.0$ ls -la
total 860
drwxrwxr-x 2 joel joel 4096 May 24 20:33 .
drwxrwxr-x 3 joel joel 4096 May 24 15:41 ..
-rwxrw-r-- 1 joel joel 322048 Jan 11 10:32 GetSomeInput.dll
-rw-rw-r-- 1 joel joel 31 May 24 15:52 __init__.py
-rwxrw-r-- 1 joel joel 431616 Oct 11 2023 Python.Runtime.dll
-rwxr-xr-x 1 joel joel 72448 May 24 20:33 pythontest
-rw-rw-r-- 1 joel joel 7171 May 24 15:41 pythontest.deps.json
-rw-rw-r-- 1 joel joel 6656 May 24 20:33 pythontest.dll
-rw-rw-r-- 1 joel joel 10964 May 24 20:33 pythontest.pdb
-rw-rw-r-- 1 joel joel 257 May 24 15:41 pythontest.runtimeconfig.json
-rw-rw-r-- 1 joel joel 38 May 24 20:31 script.py
Любая помощь приветствуется!
Обновлено: добавлено больше логов для подробностей и ясности.
Привет @TasosK, я только что проверил, его нет.





Проблема, по-видимому, вызвана тем, что sys.path (пути поиска, используемые при загрузке модулей) не содержит текущий рабочий каталог при запуске в Linux (возможно, проблема в библиотеке).
Это можно определить, запустив простой скрипт:
import sys
print('; '.join(sys.path))
Поэтому нам нужно добавить текущий каталог в sys.path, чтобы наш скрипт мог загружать модули в текущем каталоге. Для этого нам просто нужно добавить пустую строку (как указано в документации, пустая строка означает текущий каталог) в этот массив.
Чтобы применить это, нам нужно немного отредактировать код и создать область видимости Python.
using (Py.GIL())
using (var scope = Py.CreateScope()) // Scope creation
{
scope.Import("sys");
// Line below is used just to check sys.path value. It can be removed
Console.WriteLine(scope.Eval("'; '.join(sys.path)"));
scope.Exec(@"if '' not in sys.path: sys.path.insert(0, '')"); // Add current directory to sys.path if not already there
dynamic app = scope.Import(script); // Now import should work
Console.WriteLine(app.multiply(2, 4));
}
Что ж, Маттео, ты сделал это снова. Спасибо. Это сработало как сон. Очень признателен.
Есть ли у
eInnerException?