Importing modules from parent folder

前端 未结 22 2728
梦毁少年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: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

提交回复
热议问题