0

I'm using Python 3.9

I have the following structure:

parent_folder
      |
      |-->. useful_functions.py .
      |-->. script_folder_1 .
                  |
                  |-->. script_1.py
                  |-->. function_import.py
      |-->. script_folder_2 .
                  |
                  |-->. script_2.py
                  |-->. function_import.py

script_1.py and script_2.py are very similar (but not identical), and so both want to use the functions stored in useful_functions.py

I have worked out that I can import the functions from useful_functions.py by putting the following at the top of script_1.py and script_2.py:

import sys
import os
local_dir = os.getcwd()
dir_up = os.path.dirname(local_dir)
sys.path.append(dir_up)
import useful_functions as uf

This works, meaning it allows script_1.py to call functions from useful_function.py as uf.function_name(arguments)

Since this text block is identical in script_1.py and script_2.py, I wanted to pull it out and make it a function in a different file function_import.py, since that way if I need to modify it I can modify the standalone file in script_folder_1 and copy it to script_folder_2.

However, when I create function_import.py, function_import.py is able to "locally" access the functions from useful_functions.py, but script_1.py is not able to access the functions from useful_functions.py.

Details:

def function_import():
         import sys
         import os
         import re
         local_dir = os.getcwd()
         dir_up = os.path.dirname(local_dir)
         sys.path.append(dir_up)
 
         import useful_functions as uf
         print(uf.test_function())

script_1.py:

import function_import
function_import.function_import()
uf.test_function()

When I run script_1.py in the terminal, uf.test_function() returns 3, the placeholder value, inside of function_import(), but then when script_1.py calls uf.test_function(), I get: NameError: name 'uf' is not defined

Is there a way to allow a function inside a script to import modules for the script to use? Or is there some other way entirely that I should be doing this?

I read these posts and they didn't seem to have a good solution to my problem: https://stackoverflow.com/search?q=import+from+parent+directory+python&s=5452f193-c78d-4966-b69a-896fb6a5a5f8

Import Script from a Parent Directory

  • 1
    What if your app isn't running in the cwd? What do you do then? This is an awful design. You should reconsider it. Anytime you have to jump through hoops to tell your app where the code is you are likely making bad decisions. – OneMadGypsy Jun 30 '22 at 17:19
  • This looks like a complicated way to solve a simple problem. If `script_1.py` and `script_2.py` really are that similar, why not merge the scripts and refactor their differences into parameters/specific functions (e.g. `run_mode_1()` and `run_mode_2()`)? – jfaccioni Jun 30 '22 at 17:19
  • @jfaccioni script_1.py and script_2.py share ~20 functions but will have a lot of other differences. – James Minor Jun 30 '22 at 18:26
  • @OneMadGypsy if the script isn't running in the cwd it would throw an error. If I want to have functions shared by two scripts, what is the better design? The default structure would be to have both scripts in the same directory which is unsatisfactory for other design reasons. – James Minor Jun 30 '22 at 18:26
  • You're right. Making apps that error out cause they can't find their code is pretty common practice. I definitely wouldn't just put a copy of it in any project that needs it. – OneMadGypsy Jun 30 '22 at 19:10

2 Answers2

0

It's not the perfect solution but you can wrap your function into another one like so :

function_import.py:

def function_import():
     import sys
     import os
     import re
     local_dir = os.getcwd()
     dir_up = os.path.dirname(local_dir)
     sys.path.append(dir_up)
     
     import useful_functions as uf
     
     #print(uf.test_function())

def uf_test_function(*args, **kwargs):
    uf.test_function(*args, **kwargs)

script_1.py:

import function_import
function_import.function_import()
function_import.uf_test_function()
patate1684
  • 639
  • 3
  • 17
0

This doesn't define a function inside function_import.py but it does the job


function_import.py:

import sys
import os
import re
local_dir = os.getcwd()
dir_up = os.path.dirname(local_dir)
sys.path.append(dir_up)
import useful_functions as uf

useful_functions.py:

def test_function():
    print('In the test function')

script_1.py:

from function_import import uf

uf.test_function()

Outputs In the test function

The Thonnu
  • 3,578
  • 2
  • 8
  • 30