3
$\begingroup$

I am trying to use ExternalEvaluate for a Python session. For some reason I cannot import a file from there that I can import successfully when I call python some other way. I already verified that the current working directory in python is the correct one. I also added the directory to the path in two ways because it solved a similar issue here https://mathematica.stackexchange.com/a/185587/45020. For example the following outputs the correct directory (twice) and indeed the file I am trying to load is listed in the os.listdir() output.

SetDirectory[NotebookDirectory[]]
s = StartExternalSession["Python"];
ExternalEvaluate[s, "import os"];
ExternalEvaluate[s, "os.getcwd()"]
ExternalEvaluate[s, "os.chdir(" <> Directory[] <> ")"];
ExternalEvaluate[s, "sys.path.insert(1, '')"];
ExternalEvaluate[s, "os.getcwd()"]
ExternalEvaluate[s, "sys.path.insert(os.getcwd())"];
ExternalEvaluate[s, "os.listdir()"]
ExternalEvaluate[s, "import filenameWithoutPYExtension"]

I still get the no module named 'filenameWithoutPYExtension' error though.

$\endgroup$

1 Answer 1

5
$\begingroup$

In Mathematica 12.2 Directory[] returns the Documents folder in windows, instead of that use NotebookDirectory[] to get your notebook directory. In python, for importing files from unknown directories you can use sys library:

s = StartExternalSession["Python"];

ExternalEvaluate[s, 
 "import sys;sys.path.append(" <> 
  ExportString[NotebookDirectory[], "PythonExpression"] <> ")"]

ExternalEvaluate[s, "import filenameWithoutPYExtension"]

DeleteObject[s];

Also see this post.

Another point is you can use ; to run multiple lines in python:

ExternalEvaluate["Python", "import os;os.getcwd()"]

(*Out: "C:\\Users\\USERNAME\\Documents" *)

While passing strings to python directly, having single \ is problematic, for this reason, I use ToString[..., InputForm] which replace \ with \\. Using ExportString[..., "PythonExpression"] is a better option so I replace it with that.

$\endgroup$
1
  • $\begingroup$ Of course Directory[] returns the current (MMA) working directory, which might by Documents by default. In this case I had set it to NotebookDirectory[] so I will edit the question to clarify this. I do think you give the correct answer when you say that I should run ExternalEvaluate[s, "import sys;sys.path.append(" <> ToString[NotebookDirectory[], InputForm] <> ")"]. So perhaps you can explain why I had to add the full path like this. $\endgroup$
    – Kvothe
    Mar 4, 2021 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.