从导入的 python 脚本中访问导入的 python 包时出现 NameError

NameError when accessing imported python packages from within imported python script

问题陈述:

我正在 Jupyter Notebook 中编写一个程序,该程序动态编写另一个脚本 (script.py)。写入 script.py 后,写入文件 运行 的函数通过 import 语句将其写入,然后从 script.py.

调用函数

我需要在script.py中使用pandas,我在script.py的顶部导入它。在 script.py 的顶部执行 import pandas as pd 后,我得到 NameError: name 'pd' is not defined。我最初尝试省略 import 语句,因为它已经在调用程序中执行过,但我得到了同样的错误。我尝试将 import 语句放在 script.py 中的函数中,但我得到了同样的错误。

更新2,已解决: 该代码现在可以工作了。我很确定我所做的唯一一件事就是走开然后回来输入 %debug,然后重新启动内核和 运行 所有单元格。它没有找到调试的回溯。我想你可以说它很神奇,但也许它正在重新启动内核。魔术对我来说更有意义,哈哈。

更新1: 原始示例代码实际上并没有重现错误。如果我要测试 运行 它,我最好将问题隔离在实际代码中。我的错。我仍然无法解决问题,但似乎构建 write 语句的循环有些混乱。因为 运行ning 类似的代码一次没有循环就可以了。

这是我的真实代码:

import os
import pandas as pd

def read_files_in_folder(fp_list, path=None, arg_list=None):
    '''Reads a folder of csv tables into a dictionary of dataframes.
    Does this dynamically by writing a script to a file, importing the script,
    and running a function from the script.
    Parameters:
        fp_list is [str]: list of filenames or filepaths of csv files.
        path is str: (optional) filepath str filenames. os.curdir if None.
        arg_list is [str]: (optional) list of pd.read_csv() arguments to pass.
    Returns:
        df_dict is {pd.DataFrame}: dict of dataframes created from csv files.'''
    
    df_dict = {}
    
    if path is None:
        path = os.curdir
        
    if arg_list is None:
        for fp in fp_list:
            fp_var_name = fp.split('/')[-1].split('.')[0]
            df_dict[fp_var_name] = pd.read_csv(path + fp)
    else:
        args = ''
        for arg in arg_list:
            args += ', ' + arg
        with open('script.py', 'w') as file:
            file.write("""
import pandas as pd

def csvs_to_df_dict():
\tdf_dict = {}
""")
            for fp in fp_list:
                fp_var_name = fp.split('/')[-1].split('.')[0]
                statement = "\tdf_dict['" + fp_var_name + "'] = pd.read_csv('" + path + fp + "'" + args + ")\n"
                file.write(statement)
            file.write('\treturn df_dict')
        import script
        df_dict = script.csvs_to_df_dict()
    
    return df_dict

然后我执行:

csv_path = os.curdir + '/csv_tables/'
filename_list = os.listdir(path=csv_path)
df_dict = read_files_in_folder(fp_list=filename_list, path=csv_path,
                               arg_list=['index_col=0','skip_blank_lines=False'])
df_dict['abscorrup_idea.csv']

这样写 script.py:


import pandas as pd

def csvs_to_df_dict():
    df_dict = {}
    df_dict['abscorrup_idea'] = pd.read_csv('./csv_tables/abscorrup_idea.csv', index_col=0, skip_blank_lines=False)
# ... ... ...
    df_dict['sorigeq_idea'] = pd.read_csv('./csv_tables/sorigeq_idea.csv', index_col=0, skip_blank_lines=False)
    return df_dict

但是,它 returns NameError: name 'pd' is not defined 一旦它从 df_dict = script.csvs_to_df_dict() 进入 script.py,在 script.py 的 import pandas as pd 之后。请参阅下面的完整错误输出。

如果您不通过 arg_list 则它会起作用,因此首先不要创建 script.py 文件。所以,它适合我立即使用,但我想了解为什么它不能以其他方式工作。

我最初尝试将 script.py 编写为一系列语句而不是函数。我假设它只是 运行 就好像我将该代码块插入到调用它的代码中一样,但我无法从一个脚本调用到另一个脚本 df_dict 。不同的命名空间?所以,我正在尝试一个函数。

这是完整的错误输出:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-26-13999e7ca3af> in <module>
----> 1 df_dict = read_files_in_folder(fp_list=filename_list, path=csv_path,
      2                                arg_list=['index_col=0','skip_blank_lines=False'])

<ipython-input-25-4f1e04e89145> in read_files_in_folder(fp_list, path, arg_list)
     35             file.write('\treturn df_dict')
     36         import script
---> 37         df_dict = script.csvs_to_df_dict()
     38 
     39     return df_dict

~\OneDrive\Education\WGU\C749_intro_to_data_science\Module_3_Investigate_A_Dataset\Project\script.py in csvs_to_df_dict()
      1 
      2 import pandas as pd
----> 3 
      4 def csvs_to_df_dict():
      5     df_dict = {}

NameError: name 'pd' is not defined

更新前的原始示例,已清理并正确 运行ning:

例如:

# script1.py #
import pandas as pd

# The following is actually part of a function
# that is called later in the same script1,
# but I'm keeping it simple for the example.

df_dict = {}

with open('script2.py', 'w') as file:
    file.write("""
# script2.py #
import pandas as pd
def run_it():
\tdf_dict = {}
""")
    path = './csv_tables/'
    fn = 'abscorrup_idea.csv'
    file.write("\tdf_dict['abscorrup_idea'] = pd.read_csv('" + path + fn + "', index_col=0, skip_blank_lines=False)\n")
    file.write('\treturn df_dict')

import script2
df_dict = script2.run_it()
df_dict

这将写入以下文件,运行s 它,并调用函数:


# script2.py #
import pandas as pd
def run_it():
    df_dict = {}
    df_dict['abscorrup_idea'] = pd.read_csv('./csv_tables/abscorrup_idea.csv', index_col=0, skip_blank_lines=False)
    return df_dict

我已尝试重现您的错误但失败了。当我只是复制粘贴你的代码时,我得到一个 SyntaxError 因为你的转义有问题。但是这个

with open('script2.py', 'w') as file:
    file.write("""
# script2.py #
import pandas as pd
def run_it():
    df_dict = {}
    df_dict["test"] = pd.DataFrame(data={"test":[1,2,3]})
    return df_dict
""")

import script2
df_dict = script2.run_it()
df_dict["test"]

在我的机器上工作得很好。请注意,我不得不举一个不同的例子 dataframe 因为我没有你的 csv 文件。

如 post 的更新所示,以下代码有效。重新启动内核似乎已经成功了。那还是魔法。

import os
import pandas as pd

def read_files_in_folder(fp_list, path=None, arg_list=None):
    '''Reads a folder of csv tables into a dictionary of dataframes.
    Does this dynamically by writing a script to a file, importing the script,
    and running a function from the script.
    Parameters:
        fp_list is [str]: list of filenames or filepaths of csv files.
        path is str: (optional) filepath str filenames. os.curdir if None.
        arg_list is [str]: (optional) list of pd.read_csv() arguments to pass.
    Returns:
        df_dict is {pd.DataFrame}: dict of dataframes created from csv files.'''
    
    df_dict = {}
    
    if path is None:
        path = os.curdir
        
    if arg_list is None:
        for fp in fp_list:
            fp_var_name = fp.split('/')[-1].split('.')[0]
            df_dict[fp_var_name] = pd.read_csv(path + fp)
    else:
        args = ''
        for arg in arg_list:
            args += ', ' + arg
        with open('script.py', 'w') as file:
            file.write("""
import pandas as pd

def csvs_to_df_dict():
\tdf_dict = {}
""")
            for fp in fp_list:
                fp_var_name = fp.split('/')[-1].split('.')[0]
                statement = "\tdf_dict['" + fp_var_name + "'] = pd.read_csv('" + path + fp + "'" + args + ")\n"
                file.write(statement)
            file.write('\treturn df_dict')
        import script
        df_dict = script.csvs_to_df_dict()
    
    return df_dict