简体   繁体   中英

Python.Net: how to execute modules in packages?

I'm not a Python programmer so apologies if I don't get some of the terminology right (pacakages, modules)!

I have a folder structure that looks something like this:

C:\Test\System\
C:\Test\System\intercepts\
C:\Test\System\intercepts\utils1\
C:\Test\System\intercepts\utils2\

The last three folders each contain an empty __init__.py folder, while the latter two folders (\utils1, \utils2) contain numerous.py modules. For the purposes of my question I'm trying to execute a function within a module called "general.py" that resides in the \utils1 folder.

The first folder (C:\Test\System) contains a file called "entry.py", which imports the.py modules from all those sub-folders:

from intercepts.utils1 import general
from intercepts.utils1 import foobar
from intercepts.utils2 import ...
..etc..

And here is the C# code that executes the above module then attempts to call a function called "startup" in a module called "general.py" in the \utils1 folder:

const string EntryModule = @"C:\Test\System\entry.py";

using (Py.GIL())
{
    using (var scope = Py.CreateScope())
    {
        var code = File.ReadAllText(EntryModule);
        var scriptCompiled = PythonEngine.Compile(code, EntryModule);
        scope.Execute(scriptCompiled);

        dynamic func = scope.Get("general.startup");
        func();
    }
}

However I get a PythonException on the scope.Execute(...) line, with the following message:

No module named 'intercepts'
File "C:\Test\System\entry.py", line 1, in <module>
   from intercepts.utils1 import general

I'm able to do the equivalent of this using IronPython (Python 2.7), so I assume I'm doing something wrong with Python.Net (rather than changes to how packages work in Python 3.x).

I'm using the pythonnet 3.0.0 NuGet package by the way.

Edit I've tried importing my "entry.py" module as follows:

dynamic os = Py.Import("os"); 
dynamic sys = Py.Import("sys");                   
sys.path.append(os.path.dirname(EntryModule)); 
Py.Import(Path.GetFileNameWithoutExtension(EntryModule));

It now appears to get a little further, however there's a new problem:

In the "entry.py" module you can see that it first imports a module called "general", then a module called "foobar". "foobar.py" contains the line import general . When I run my C#, the stack trace is now as follows:

No module named 'general'
File "C:\Test\System\intercepts\utils1\foobar.py", line 1, in <module>
import general
  File "C:\Test\System\entry.py", line 2, in <module>
from intercepts.utils1 import foobar

Why can't the second imported module ("foobar") "see" the module that was imported immediately before it ("general")? Am I even barking up the right tree by using Py.Import() to solve my original issue?

This turned out to be a change in how Python 3 handles imports, compared to 2, and nothing to do with Python.Net.

In my "foobar.py" module I had to change import general to from. import general from. import general . The issue is explained here but I've included the pertinent section below:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM