Importing modules from parent folder

前端 未结 22 2698
梦毁少年i
梦毁少年i 2020-11-21 23:19

I am running Python 2.5.

This is my folder tree:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(I also have __init

相关标签:
22条回答
  • 2020-11-21 23:31

    You can use OS depending path in "module search path" which is listed in sys.path . So you can easily add parent directory like following

    import sys
    sys.path.insert(0,'..')
    

    If you want to add parent-parent directory,

    sys.path.insert(0,'../..')
    

    This works both in python 2 and 3.

    0 讨论(0)
  • 2020-11-21 23:31

    In a Jupyter Notebook

    As long as you're working in a Jupyter Notebook, this short solution might be useful:

    %cd ..
    import nib
    

    It works even without an __init__.py file.

    I tested it with Anaconda3 on Linux and Windows 7.

    0 讨论(0)
  • 2020-11-21 23:32

    Here is an answer that's simple so you can see how it works, small and cross-platform.
    It only uses built-in modules (os, sys and inspect) so should work
    on any operating system (OS) because Python is designed for that.

    Shorter code for answer - fewer lines and variables

    from inspect import getsourcefile
    import os.path as path, sys
    current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
    sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
    import my_module  # Replace "my_module" here with the module name.
    sys.path.pop(0)
    

    For less lines than this, replace the second line with import os.path as path, sys, inspect,
    add inspect. at the start of getsourcefile (line 3) and remove the first line.
    - however this imports all of the module so could need more time, memory and resources.

    The code for my answer (longer version)

    from inspect import getsourcefile
    import os.path
    import sys
    
    current_path = os.path.abspath(getsourcefile(lambda:0))
    current_dir = os.path.dirname(current_path)
    parent_dir = current_dir[:current_dir.rfind(os.path.sep)]
    
    sys.path.insert(0, parent_dir)
    
    import my_module  # Replace "my_module" here with the module name.
    

    It uses an example from a Stack Overflow answer How do I get the path of the current executed file in Python? to find the source (filename) of running code with a built-in tool.

    from inspect import getsourcefile  
    from os.path import abspath  
    

    Next, wherever you want to find the source file from you just use:

    abspath(getsourcefile(lambda:0))
    

    My code adds a file path to sys.path, the python path list
    because this allows Python to import modules from that folder.

    After importing a module in the code, it's a good idea to run sys.path.pop(0) on a new line
    when that added folder has a module with the same name as another module that is imported
    later in the program. You need to remove the list item added before the import, not other paths.
    If your program doesn't import other modules, it's safe to not delete the file path because
    after a program ends (or restarting the Python shell), any edits made to sys.path disappear.

    Notes about a filename variable

    My answer doesn't use the __file__ variable to get the file path/filename of running
    code because users here have often described it as unreliable. You shouldn't use it
    for importing modules from parent folder in programs used by other people.

    Some examples where it doesn't work (quote from this Stack Overflow question):

    • it can't be found on some platforms • it sometimes isn't the full file path

    • py2exe doesn't have a __file__ attribute, but there is a workaround
    • When you run from IDLE with execute() there is no __file__ attribute
    • OS X 10.6 where I get NameError: global name '__file__' is not defined
    0 讨论(0)
  • 2020-11-21 23:32

    I had a problem where I had to import a Flask application, that had an import that also needed to import files in separate folders. This is partially using Remi's answer, but suppose we had a repository that looks like this:

    .
    └── service
        └── misc
            └── categories.csv
        └── test
            └── app_test.py
        app.py
        pipeline.py
    

    Then before importing the app object from the app.py file, we change the directory one level up, so when we import the app (which imports the pipeline.py), we can also read in miscellaneous files like a csv file.

    import os,sys,inspect
    currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
    parentdir = os.path.dirname(currentdir)
    sys.path.insert(0,parentdir)
    
    os.chdir('../')
    from app import app
    

    After having imported the Flask app, you can use os.chdir('./test') so that your working directory is not changed.

    0 讨论(0)
  • 2020-11-21 23:34

    Don't know much about python 2.
    In python 3, the parent folder can be added as follows:

    import sys 
    sys.path.append('..')
    

    ...and then one is able to import modules from it

    0 讨论(0)
  • 2020-11-21 23:43

    Here is more generic solution that includes the parent directory into sys.path (works for me):

    import os.path, sys
    sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
    
    0 讨论(0)
提交回复
热议问题