Вызов IronPython из C # (с SciPy) завершается с ошибкой ImportException: нет модуля с именем mtrand

У меня есть библиотека Python, которую я пытаюсь использовать через вызов IronPython (v2.7 RC1 [2.7.0.30]) из приложения C #. Библиотека довольно широко использует NumPy и SciPy, которые действительно работают с SciPy и NumPy для .NET при запуске с использованием ipy из командной строки следующим образом:

ipy.exe -X:Frames file_from_lib_importing_numpy.py

Однако, когда я вызываю IronPython из C #, используя приведенный ниже код, возникает исключение:

ImportException
"No module named mtrand"
   at Microsoft.Scripting.Runtime.LightExceptions.CheckAndThrow(Object value)
   at IronPython.Runtime.Operations.PythonOps.ImportStar(CodeContext context, String fullName, Int32 level)
   at Microsoft.Scripting.Interpreter.ActionCallInstruction3.Run(InterpretedFrame frame)
   ...
   at Microsoft.Scripting.SourceUnit.Execute(Scope scope, ErrorSink errorSink)
   at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)
   at Microsoft.Scripting.Hosting.ScriptEngine.ExecuteFile(String path)
   at Microsoft.Scripting.Hosting.ScriptRuntime.ExecuteFile(String path)
   at Microsoft.Scripting.Hosting.ScriptRuntime.UseFile(String path)
   ...

Код C # (его часть), который вызывает IronPython, выглядит следующим образом:

    ScriptEngine _engine;

    var opts = new Dictionary<string, object>();
    opts["Frames"] = ScriptingRuntimeHelpers.True;
    _engine = Python.CreateEngine(opts);

    var sp = _engine.GetSearchPaths();
    sp.Add(@"c:\Program Files\IronPython 2.7");
    sp.Add(@"c:\Program Files\IronPython 2.7\DLLs");
    sp.Add(@"c:\Program Files\IronPython 2.7\Lib");
    sp.Add(@"c:\Program Files\IronPython 2.7\Lib\site-packages");
    sp.Add(_path);
    _engine.SetSearchPaths(sp);

    var _runtime = _engine.Runtime;
    var scope = _runtime.ExecuteFile(Path.Combine(_path, "mytest.py"));

В целях тестирования я выполняю следующий файл mytest.py:

    import sys
    sys.path.append(r'c:\Program Files\IronPython 2.7')
    sys.path.append(r'c:\Program Files\IronPython 2.7\DLLs')
    sys.path.append(r'c:\Program Files\IronPython 2.7\Lib')
    sys.path.append(r'c:\Program Files\IronPython 2.7\Lib\site-packages')

    import os, os.path
    cd = os.path.dirname(__file__)
    if not cd in sys.path:
        sys.path.append(os.path.dirname(__file__))

    import numpy as np
    print 'OK'

    x = np.array([1,2])
    print x

Что не удается в строке 12 'import numpy as np'. Проблема в том, что файл __init__.py в IronPython 2.7 \ Lib \ site-packages \ numpy \ random \ содержит следующую строку

from mtrand import *

который терпит неудачу. Обратите внимание, что mtrand - это не модуль, это каталог. Я не могу придумать ничего другого, что бы я мог попытаться выполнить, поэтому я был бы очень признателен за любую вашу помощь. Большое Вам спасибо.


person PeterParameter    schedule 02.04.2011    source источник
comment
Каков результат print sys.path, И дает ли sys.path.append(r'c:\Program Files\IronPython 2.7') после import sys такие же результаты?   -  person Preet Sangha    schedule 03.04.2011
comment
Вы правы, при вызове из C # sys.path не содержит путей, установленных в приложении. Кроме того, когда я добавляю строку sys.path.append(r'c:\Program Files\IronPython 2.7'), происходит сбой без модуля с именем numpy. Мне действительно нужно настраивать пути в каждом файле Python, который я хочу использовать из приложения C #?   -  person PeterParameter    schedule 03.04.2011
comment
Другими словами, какова цель настройки путей поиска, если они не распространяются в среду выполнения Python?   -  person PeterParameter    schedule 03.04.2011
comment
Добавление путей к файлу python не решило проблему - по-прежнему возникло такое же исключение. Кажется, что sys.path настроен правильно (содержит добавленные пути, каталоги Lib и Dll CWD приложения C # и каталог исполняемого файла), и numpy по крайней мере начинает импортировать.   -  person PeterParameter    schedule 03.04.2011


Ответы (2)


Не лучший соултион, но у меня работает:

import sys
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7')
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7\DLLs')
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7\Lib')
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7\Lib\site-packages')

import clr
clr.AddReference('mtrand.dll')

import numpy
import scipy

print numpy.__version__
print scipy.__version__

Я надеюсь, что это помогает.

person Vaszil    schedule 04.04.2011
comment
хм, а как именно вы собрали mtrand.dll? Я пробовал скрипт pyc.py, т.е. запускал ipy pyc.py /main:..\..\Lib\site-packages\numpy\random\mtrand\generate_mtrand_c.py /out:mtrand /target:dll, но это тоже не помогло - person PeterParameter; 08.04.2011
comment
Я не строил. Установщик скопирует его в папку c:\Program Files (x86)\IronPython 2.7\DLLs. - person Vaszil; 10.04.2011
comment
Хороший. Это сработало для меня после многих головных болей ... Если это поможет кому-то, я вызываю это на C # вот так ... var lang = Python.CreateLanguageSetup (null); lang.Options [Frames] = ScriptingRuntimeHelpers.True; var setup = new ScriptRuntimeSetup (); setup.LanguageSetups.Add (lang); var runtime = new ScriptRuntime (настройка); var engine = runtime.GetEngine (py); engine.ExecuteFile (mytest.py); - person David Rinck; 17.12.2011
comment
У меня тоже сработало - однако я понятия не имею, зачем это нужно. В конце концов, все библиотеки DLL находятся в одном каталоге, а другие, похоже, загружаются, не выполняя для них AddReference. - person Sven; 10.06.2015

Я обнаружил, что в моем ActivePython V2.7.0.2 это работает:

sys.path.append(r'C:\\Examples')
import examples

(при условии, что examples.py находится в C: \ examples). Это не (без r):

sys.path.append('C:\\Examples')
import examples

Потому что я понял это:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named examples

Вывод: помните о р ''!

person Paul Bilokon    schedule 22.06.2011
comment
В строковом литерале с префиксом r управляющие последовательности, начинающиеся с \, отключены. Это удобно для путей к файлам, поскольку \ - это разделитель путей, и вы не хотите, чтобы он запускал escape-последовательность. (r'C: \ Примеры ') == (' C: \\ Примеры ') - person Vaszil; 04.09.2014