0

When I searched for this problem, I mostly saw how to import from a txt file or other file format. Not from a python file.

I need to write a function (get_seeds()) that takes in a path in string and extract a variable from that .py file. That .py file supposedly only has one variable named seeds.

Given:

path = ./data/M060812_Yac128/seeds.py

seeds = {
    "HLS1": {'X': 44, 'Y': 52},
    'HLS2A': {'X': 108, 'Y': 66},
    'HLS2B': {'X': 91, 'Y': 85},
    'FLS1': {'X': 56, 'Y': 39},
    'FLS2': {'X': 104, 'Y': 61},
    'BCC2': {'X': 68, 'Y': 69},
    'BCC2S2': {'X': 92, 'Y': 72},
    'mBC': {'X': 34, 'Y': 30}
}

get_seeds.py:

def get_seeds(path):
    Path = os.path.normpaath(path)
    from Path import seeds
    return seeds

This obviously doesn't work... because I assume from...import... needs to be outside of the function.

4
  • Your assumption is not correct. Look at this answer Commented May 14, 2020 at 2:50
  • 1
    @mmrbulbul you're right, but regardless you can't dynamically import from another user script using this syntax because the module name is a string Commented May 14, 2020 at 2:55
  • No; because from X import Y treats X as a package or module name, and doesn't work with an existing variable. What you are trying to do is typically called dynamic import and there are several previous questions you can look up that may or may not be close enough for your purposes; I'm not confident picking the best one for you because your exact needs may differ from what I see described here. Commented May 14, 2020 at 3:20
  • you can make seeds.py a module and import it like any other import, then access the seeds variable in your script. See answer below Commented May 14, 2020 at 3:28

2 Answers 2

1

Try using importlib.import_module instead to import where the name of the module is a string. Additionally, use sys.path to include the path of the folder where the script resides so that you can import it by name and use it in your script

import os
import importlib

def get_seeds(path):
    Path = os.path.normpath(path)
    folders = Path.split('/') # create list of each folder component of the path
    folder_path = '/'.join(folders[:-1]) # remove the file from the path to specify path to the folder containing script
    sys.path.insert(1, folder_path) # add folder path to sys path so python can find module

    mod = importlib.import_module(folders[-1][:-3]) # get rid of .py extension and use only name of the script rather than entire path
    return mod.seeds
Sign up to request clarification or add additional context in comments.

Comments

1

This will work if your file is static and not generated. If you need to be able to access multiple files that could have any name, there is another answer here that will work better.

if you put an __init__.py file (just a blank file with that name) in ./data/ and ./data/M060812_Yac128/ you can from data.M060812_Yac128.seeds import seeds then call the function.

This makes the subfolders python modules

Directory structure:

enter image description here

seeds.py:

seeds = {
    "HLS1": {'X': 44, 'Y': 52},
    'HLS2A': {'X': 108, 'Y': 66},
    'HLS2B': {'X': 91, 'Y': 85},
    'FLS1': {'X': 56, 'Y': 39},
    'FLS2': {'X': 104, 'Y': 61},
    'BCC2': {'X': 68, 'Y': 69},
    'BCC2S2': {'X': 92, 'Y': 72},
    'mBC': {'X': 34, 'Y': 30}
}

Main python file:

from data.M060812_Yac128.seeds import seeds

print(seeds)

Output:

{'HLS1': {'X': 44, 'Y': 52}, 'HLS2A': {'X': 108, 'Y': 66}, 'HLS2B': {'X': 91, 'Y': 85}, 'FLS1': {'X': 56, 'Y': 39}, 'FLS2': {'X': 104, 'Y': 61}, 'BCC2': {'X': 68, 'Y': 69}, 'BCC2S2': {'X': 92, 'Y': 72}, 'mBC': {'X': 34, 'Y': 30}}

3 Comments

And what happens when the path is different? You can't (shouldn't) place an __init__.py file in each different directory. Also, there's no guarantee that that path is in the system PATH so it still may not resolve the package/module
I would ask why/how a python file is being generated like that instead of json, this will work if it is a static python file
A valid question, but OP's requirements (whyever they may be so) explicitly make it clear that this approach will not work

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.