1

I'm 'reposting' this question with more detail because I feel it was misunderstood the first time. I have a folder structure that looks like so:

folder w space
       ├── folder1
       │      └── subfolder1
       │              └── file_1.py
       └── folder2
              └── folder w space2
                       └── file_2.py
                       └── __init__.py

I'm needing to have file_1.py import the methods from file_2.py. Notice that file_2.py, in relation to file_1.py, is 3 directories up and then 3 directories down. I would, in theory, write the relative import as so:

from ...folder2 import folder w space2.file2

However this is not valid due to the spacing in the subfolder. An absolute import is even worse because the base folder contains spaces too:

from folder w space.folder2.folder w space2.file2 

With this, how can I access the contents of file_2.py without:

  1. Renaming the folders (I don't own them so I can't even if I wanted to)
  2. Without using sys.path.append() (does not work well in our production env)
  3. Moving file_2.py (for organization must stay where it is)

Any help would be immensely appreciated!

mmarion
  • 859
  • 8
  • 20

2 Answers2

0

You can use importlib.import_module

# bar.py
import importlib
importlib.import_module("folder with spaces.foo")     

# folder with spaces/foo.py
print('Hello World')
AdamMcKay
  • 549
  • 6
  • 15
0

The built-in __import__() allows to support spaces in import statements:

sample_with_spaces = __import__("sample with spaces.foo")

sample_with_spaces.foo.hello()

Found it in this question: https://stackoverflow.com/a/9123555/6180150

filename is used as the identifier for imported modules (i.e. foo.py will be imported as foo) and Python identifiers can't have spaces, this isn't supported by the import statement

So instead of letting the import statement set the identifier, you do that manually by assigning __import__("sample with spaces.foo") to the identifier you select yourself. In my example it is the identifier sample_with_spaces.

EDIT:

I think in your case when executing the script within a subfolder, it's the easiest way to update the working dir like below.

import os

os.chdir("..") # move up as much as needed
sample_with_spaces = __import__("sample with spaces.foo")

sample_with_spaces.foo.hello()
schilli
  • 1,700
  • 1
  • 9
  • 17
  • 1
    As the [documentation](https://docs.python.org/3/library/functions.html#__import__) says, this method is discouraged in favour of using `importlib.import_module()` – AdamMcKay May 13 '21 at 09:17
  • I think this only works for imports that are relative to the cwd, I think `__import__` wouldn't work for going up directories as I'd need it to – mmarion May 13 '21 at 17:24
  • I think it would work. But important is, from where you run your python file. Are you running it from the child folder or from the root folder? Depending on that you would have to set your imports and for simplicity root is then always the best option. – schilli May 13 '21 at 17:55
  • @schilli yes I should have clarified that, I'm running main from 'subfolder1' in my diagram. I actually don't own that file either meaning I can't move it. I think that's my primary issue. Any suggestions or how to use `__import__` for this case? – mmarion May 13 '21 at 19:16
  • @mmarion I see. It sounds like a really tough setting. I updated my question with my best idea for importing from a parent dir by changing the working dir. Like AdamMcKay said the python docs suggest to use importlib instead of `__import__`, but I didn't adapt my code in that direction, so it'll be best if you follow that advise, too. – schilli May 13 '21 at 22:13