1

I am trying to call a python class from my c# file in Unity3d. Numpy and os modules work fine.

 void Start()
    {
        startTime = Time.time;

        using (Py.GIL())
        {
            dynamic np = Py.Import("numpy");
            UnityEngine.Debug.Log(np.cos(np.pi * 2));

            dynamic sin = np.sin;
            UnityEngine.Debug.Log(sin(5));

            double c = np.cos(5) + sin(5);
            UnityEngine.Debug.Log(c);

            dynamic a = np.array(new List<float> { 1, 2, 3 });
            UnityEngine.Debug.Log(a.dtype);

            dynamic b = np.array(new List<float> { 6, 5, 4 }, dtype: np.int32);
            UnityEngine.Debug.Log(b.dtype);

            UnityEngine.Debug.Log(a * b);
            dynamic os = Py.Import("os");
            UnityEngine.Debug.Log(os.getcwd());

            dynamic test = Py.Import("clrTest"); // this throws me an error
        }
    }

clrTest is my custom class clrTest.py

class clsMyTest:
    """clsTest.clsMyTest class"""

    @staticmethod
    def Test03():
        return 42

    def Test04():
        return 42

def Test01():
    return 42

@staticmethod
def Test02():
    return 42

I get this following error

PythonException: ModuleNotFoundError : No module named 'clrTest'
Python.Runtime.Runtime.CheckExceptionOccurred () (at <38fa310f96774b388b3fb5f7d3ed5afc>:0)
Python.Runtime.PythonEngine.ImportModule (System.String name) (at <38fa310f96774b388b3fb5f7d3ed5afc>:0)
Python.Runtime.Py.Import (System.String name) (at <38fa310f96774b388b3fb5f7d3ed5afc>:0)

I tried placing my python file in same directory as the c# file, in the root directory and in the Plugins foler. Still I get this error. What to do?

MrRobot9
  • 2,402
  • 4
  • 31
  • 68
  • 1
    Have you tried to Rebuild, restart the project? And could it be that the name of the file is actually `clrTest.py` instead of `clrTest` for `Py.Import`? – vvilin Oct 18 '19 at 18:27

1 Answers1

0

Pythonnet's Py.Import() behaves the same as Python "import" statement. For a module to be successfully imported, the module has to be in one of the locations of Python interpreter's search path. The interpreter search path is platform-specific and can be modified. Refer to Python documentation for details: Modifying Python’s Search Path.

Under Windows, I usually resort to one of the two options:

  1. Modify PYTHONPATH environment variable for the managed process:

    Environment.SetEnvironmentVariable("PYTHONPATH", @"D:\MyPythonModules\", EnvironmentVariableTarget.Process);  
    
  2. Modify Python's sys.path by executing python code string with pythonnet:

        using (Py.GIL())
        {
            int returnValue = PythonEngine.RunSimpleString("import sys;sys.path.insert(1, 'D:/MyPythonModules/');");
            if (returnValue != 0)
            {
                 //throw exception or other failure handling
            }
        }
    

The advantage of using these options over others listed in Python documentation is that you don't modify your Python installation. The second option will also work with embeddable Python which ignores environment variables. The advantage of modifying PYTHONPATH only for the specific process is that you don't influence other processes in the system. However, if you need only to test something quickly, you can directly modify the system's PYTHONPATH environment variable.

ika
  • 156
  • 4