简体   繁体   中英

Import module from parent folder but still working in child directory

I'm relatively new to Python and I need to make a script which can call a function from a file in parent folder. In simple terms, the directory now looks like this:

  • parentModule.py
  • childDirectory/
    - childScript.py

parentModule.py contains the following script

def runFunction():
    print('function triggered')
    return 1

childScript.py contains the following script

import sys, os

sys.path.append( os.path.dirname(os.path.realpath(__file__))+'/..')
import parentModule

def runChildMain():
    '''
    run runFunction from parentModule.py
    '''
    parentModule.runFunction()

    # Do stuff in childDirectory, for example, create an empty python file
    open('test', 'a').close()

runChildMain()

I need to be able to run childScript.py on its own because later on the childScript.py will be run as a subprocess. The problem is that when I use sys.path, which I did not mention before, the command to create a file with open() runs in the parent directory, not in the childDirectory. So, this results in the file 'test' created in the parentDirectory, but I need it to be created inside childDirectory.

I know it is possible to go down a directory ie:

parentModule.py:

from childDirectory.childScript import runChildMain
def runFunction():
    runChildMain()
runFunction()

childScript.py

def runChildMain():
    print("HIT Run child main")

if __name__ == "__main__":
    runChildMain()

if the file structure has to be set up that way though you may have to use:

sys.path.append( os.path.dirname(os.path.realpath(__file__))+'/..')

So I have found the solution. Basically after importing the parent module, I need to change the working directory to the child directory in order to continue do stuff inside the child directory.

Code below is the answer for my question

# Import from parent directory -- https://stackoverflow.com/questions/67631/how-do-i-import-a-module-given-the-full-path?rq=1
import importlib.util
import sys, os
spec = importlib.util.spec_from_file_location("parentModule", "parentModule.py")
foo = importlib.util.module_from_spec(spec)
sys.modules["module.name"] = foo
spec.loader.exec_module(foo)

# Change working directory to child directory
os.chdir("childDir")

def runChildMain():
    foo.runFunction()

    # This will be executed in the child directory
    open('test2', 'a').close()

runChildMain()

The correct way of doing this is to run the script with the -m switch

python -m childDirectory.childScript # from the parent of childDirectory

Then in childScript you do a simple from parentModule import runFunction . Hacking the sys path is bad practice and using chdir should be also avoided (leads to nasty surprises)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM