【问题标题】:NameError when accessing imported python packages from within imported python script从导入的 python 脚本中访问导入的 python 包时出现 NameError
【发布时间】:2020-10-15 05:47:41
【问题描述】:

问题陈述:

我正在 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 的函数中,但我得到了同样的错误。

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

更新1: 原始示例代码实际上并未重现该错误。如果我要测试运行它,我最好将问题隔离在实际代码中。我的错。我仍然无法解决这个问题,但似乎构造写语句的循环有些东西搞砸了。因为在没有循环的情况下运行类似的代码一次。

这是我的真实代码:

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

但是,一旦它从df_dict = script.csvs_to_df_dict() 进入script.py,在script.py 的import pandas as pd 之后,它就会返回NameError: name 'pd' is not defined。完整的错误输出见下文。

如果您不传递 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

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

例如:

# 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

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


# 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

【问题讨论】:

    标签: python import scripting nameerror


    【解决方案1】:

    我试图重现您的错误但失败了。当我只是复制粘贴您的代码时,我得到一个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 文件。

    【讨论】:

    • 哈哈,我应该测试一下我的示例代码,抱歉。我会解决的。我喜欢你创建写入字符串的方式。一旦我在测试示例中实现了它,它就起作用了。我将在真实脚本中尝试并报告。谢谢!
    • 我更新了帖子以包含我正在处理的实际代码。我无法用三引号构造写入字符串,因为我需要在循环中动态组合它。那个循环有一些东西把它搞砸了。想再看一遍吗?再次感谢!
    • 没关系,代码现在可以工作了。我很确定我唯一做的就是走开然后回来输入%debug,然后重新启动内核并运行所有单元。它没有找到要调试的回溯。我想你可以说这很神奇,但也许它正在重新启动内核,这对我来说是零意义。魔术对我来说更有意义。
    • 哦,这是由于导入的工作方式。你不能真的两次导入东西。你被困在你第一次导入时的样子。不过,Jupyter 确实试图提供魔法来解决这个问题。如果你经常遇到这个问题,你可以试试%load_ext \n autoreload %autoreload 2
    • @KalebCoberly 那么现在一切都好吗?或者您没有接受答案这一事实是否应该告诉人们还有问题?
    【解决方案2】:

    从帖子更新中可以看出,以下代码有效。重新启动内核似乎已经成功了。那就是魔法。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-24
      • 2019-07-03
      • 2021-07-29
      • 1970-01-01
      • 2014-08-20
      • 2018-02-08
      • 1970-01-01
      • 2020-07-19
      相关资源
      最近更新 更多