0

I'm getting this weird error when executing the same file in two different ways.

I have a child.py script that contains the following:

import seaborn as sns
import numpy as np

iris = sns.load_dataset('iris')

def fun1(df, cut = 2):
    df = df[df['sepal_length'] > cut]
    df = df.groupby('species')\
        .agg({'sepal_width' : np.mean})\
        .reset_index()
    return df

# Test fun1()
fun1(iris)
print('fun1 is defined...')

def fun2(df, cut = 2):
    df_comp = fun1(df, cut)
    df = df.merge(df_comp, on = 'species')
    return df

# Test fun2
fun2(iris)
print('Success!')

When I run it like this it runs:

> python child.py
fun1 is defined...
Success!

But I need to run this script from another called parent.py

import os
import numpy as np

def run(filename):
    exec(open(filename).read())

run('child.py')

But when I try to run it from the parent it gives me an error saying 'fun1' is not defined. This is particularly weird because it literally ran fun1() just before the error.

> python parent.py
fun1 is defined...
Traceback (most recent call last):
  File "parent.py", line 9, in <module>
    run('child.py')
  File "parent.py", line 7, in run
    exec(open(filename).read())
  File "<string>", line 27, in <module>
  File "<string>", line 23, in fun2
NameError: name 'fun1' is not defined

A few other comments:

  • I'm loading numpy on both because if I only call them in one the error is NameError: name 'np' is not defined. Which I believe is related to the same scope issue, but not sure how.
  • I'm not particularly attached to using exec(open(filename).read()) but I do need to call one script from the other.
Leonardo Viotti
  • 476
  • 1
  • 5
  • 15
  • 1
    Have you tried `import child`? You can also use the `subprocess` module to run other Python scripts. You should create a [mre] that doesn't use all those third-party modules and see what happens. – martineau Mar 23 '21 at 21:34
  • @martineau, I have tried without the third-party modules and I don't get the error, that's why I included them. With `import child` it actually work, but I actually have a lot of files in different folders so not sure if it is a good solution. Thanks! – Leonardo Viotti Mar 24 '21 at 01:54
  • Try using `subprocess` to run the Python executable (`sys.executable`) and pass it the path to the `child.py` file as an argument. You could also use [`importlib.import_module()`](https://docs.python.org/3/library/importlib.html#importlib.import_module) but I'm not very familiar with it. – martineau Mar 24 '21 at 02:13
  • The answers to the question [How to import a module given the full path?](https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path) might be helpful. – martineau Mar 24 '21 at 02:21

0 Answers0