LESSWRONG
LW

ProgrammingPractical
Frontpage

12

Importing a Python File by Name

by jefftk
25th Jan 2024
jefftk
1 min read
7

12

ProgrammingPractical
Frontpage

12

Importing a Python File by Name
6Nathan Helm-Burger
4Nisan
-1Gunnar_Zarncke
4jefftk
2Gunnar_Zarncke
4jefftk
2Gunnar_Zarncke
New Comment
7 comments, sorted by
top scoring
Click to highlight new comments since: Today at 4:08 AM
[-]Nathan Helm-Burger1y61

Ugh, this has caused me so many hours of pain over the years. Especially in the context of importing into jupyter notebooks, which can add a layer of complication.

Reply
[-]Nisan1y40

This article saved me some time just now. Thanks!

Reply
[-]Gunnar_Zarncke1y-1-2

Why not use exec()?

Reply1
[-]jefftk1y40

You mean with open("/path/to/foo.py") as inf: exec(inf.read())? I'd expect that to work, but:

  • It doesn't do namespacing (so instead of being foo.bar any symbols in foo will just end up as bar)

  • I'd really prefer not to use exec: there are so many ways to misuse it, and it's hard to tell if it's being used properly from looking at it. Much less of an issue in research code, but I'd still rather not.

Reply
[-]Gunnar_Zarncke1y20

Yes, that's what I meant. There are many ways to abuse exec, but your way of using importlib.import_module with tweaked path has the same security issues. One death you have to die and exec seems to be the simplest. 

Maybe you explain a bit more why you want to pull out the section from the main file. What is the real purpose? 

Reply
[-]jefftk1y40

I want to call the section from two different pieces of code I'm experimenting with right now. At some point some of it will likely end up in a real system, but right now it's all very exploratory.

Reply
[-]Gunnar_Zarncke1y20

Then security doesn't matter and you can do whatever is simplest. Even the module space doesn't matter.

Reply
Moderation Log
Curated and popular this week
7Comments

Let's say you have a python script:

2024-01-24--evaluate-chimeras.py
And you want to pull a section of it out into a separate file:
2024-01-25--strand-split-artifacts.py
You would hope you could just do something like:
import "/path/to/2024-01-25--strand-split-artifacts.py"
But this doesn't work: import wants a module name, not a filename. The simplest way I know to import a python file from a path is:
import sys
import importlib

sys.path.append("/path/to/")
ssa = importlib.import_module("2024-01-25--strand-split-artifacts")
There are a lot of complicated ways to do this, some of which avoid needing to add something to sys.path, but for quick one-off research code better to keep it simple.