简体   繁体   中英

How can I execute a file (that imports other modules) from a Python script in a different directory without using relative imports in the file?

I want to trace the function-sequence called by running a file driver.py . This file is in another directory and the script that I am using to trace the functions called when driver.py is used is in another(different) directory. When I go to the directory of driver.py and run it in the terminal, it runs fine. However, when I run the same function from my Python script(the one used for generating functional sequence), I get No module found error s for the imports that driver.py makes. The condition is, that I cannot change driver.py at all.

This is my file structure: /Users/aviralsrivastava/dev/generate_uml/generate_ruml.py (A) calls a function in /Users/aviralsrivastava/dev/generate_uml/generate_sequence_diagram.py (B) that imports /Users/aviralsrivastava/Desktop/source_code_to_study/driver.py (driver).

This is how A calls B:

generate_sequence_diagram = GenerateSequenceDiagram('/Users/aviralsrivastava/Desktop/source_code_to_study/driver.py')
called_functions = generate_sequence_diagram.get_called_functions('main_2')

This is what B looks like:

from trace import Trace
import importlib
# from driver import main_2
import os


class GenerateSequenceDiagram:
    def __init__(self, driver_module):
        # self.driver_module = __import__(driver_module)
        print('inside init of gen seq diag, dir is: {}'.format(os.getcwd()))
        # self.driver_module = importlib.import_module(driver_module)
        self.driver_module_spec = importlib.util.spec_from_file_location('driver', driver_module)
        self.driver_module = importlib.util.module_from_spec(self.driver_module_spec)

    def get_called_functions(self, driver_function):
        self.driver_module_spec.loader.exec_module(self.driver_module)
        self.driver_function = getattr(self.driver_module, driver_function)
        self.driver_function()
        # print(dir(self.driver_function))
        # print(self.driver_function.__name__)
        tracer = Trace(countfuncs=1)
        tracer.run('{}()'.format(self.driver_function.__name__))
        results = tracer.results()
        called_functions = results.calledfuncs
        return called_functions


# ob = GenerateSequenceDiagram('driver')
# print(ob.get_called_functions('main_2'))

This is what driver looks like:

# from .source_code_to_study import car, transport, vehicles
import sys
# sys.path.insert(0, '/Users/aviralsrivastava/dev/source_code_to_study')
import car, vehicles, transport

# def main():
#     tractor_pollution_permit = transport.TractorPollutionPermit()
#     tractor_pollution_permit.fetch_tractor(2018, True)
#     tractor_pesticides = transport.TractorPesticides()
#     tractor_pesticides.fetch_pesticides_permit(11)
#     car_ = car.Car(model='Tesla')
#     car_.pollution_permit(20000)
#     bike = car.Bike('Harley', 2019)
#     bike.pollution_permit(200000)
#     bike.check_farzi()


def main_2():
    print('Inside main_2 func')
    car_ = car.Car(model='Tesla')
    car_.pollution_permit(20000)
    bike = car.Bike('Harley', 2019)
    bike.pollution_permit(200000)
    bike.check_farzi()
    # tractor_pollution_permit = transport.TractorPollutionPermit()
    # tractor_pollution_permit.fetch_tractor(2018, True)
    # tractor_pesticides = transport.TractorPesticides()
    # tractor_pesticides.fetch_pesticides_permit(11)

main_2()

The contents of the directory in which driver.py is stored are:

.
├── car.py
├── driver.py
├── transport.py
└── vehicles.py

0 directories, 4 files

Since this seems like a one of thing, appending the directory with the files you need to import to sys.path , seems like a reasonable enough solution.

import sys

sys.path.append('directory/path/with/files/to/import')

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