在一个文件中加载大型对象并将其导入其他Python文件是一种好的做法吗?

在一个文件中加载大型对象并将其导入其他Python文件是一种好的做法吗?,python,import,Python,Import,我最近在一个Python项目中意识到,我需要加载大量大小相当大的对象(可能是千兆字节…) 看来我有两个选择: 将它们加载到我的顶级文件中,并将它们传递给需要它们的函数。但是,如果许多函数需要访问许多大型对象,那么这很容易变得令人厌烦 在一个文件中加载所有大型对象,并在整个项目的任何Python文件中按需导入所需的对象。现在这个看起来已经够整洁了。在large_objects.py文件中,我会有这样的内容: huge_file_1 = load_huge_file_1() huge_file_2

我最近在一个Python项目中意识到,我需要加载大量大小相当大的对象(可能是千兆字节…)

看来我有两个选择:

  • 将它们加载到我的顶级文件中,并将它们传递给需要它们的函数。但是,如果许多函数需要访问许多大型对象,那么这很容易变得令人厌烦

  • 在一个文件中加载所有大型对象,并在整个项目的任何Python文件中按需导入所需的对象。现在这个看起来已经够整洁了。在
    large_objects.py
    文件中,我会有这样的内容:

    huge_file_1 = load_huge_file_1()
    huge_file_2 = load_huge_file_2()
    huge_file_3 = load_huge_file_3()
    
  • 现在,我不确定第二种方法是否足够有效。例如,每次导入某些内容时,Python解释器都会执行load_SHAGE_file_i()


    另外,您还有其他建议吗?

    考虑几点。因此,首先,当文件被导入时,文件中的任何内容都将被执行,这通常是立即执行的。所以我经常在文件中预先加载。但它不一定要在一个地方。您可以在许多不同的文件中执行此操作。例如:

    慢:

    快速:

    然而,另一个考虑因素是记忆。如果你在早期将很多对象加载到内存中,即使它们没有被使用,你也会随身携带它们。Python使用引用计数,而不是垃圾收集,这意味着,如果有任何剩余的对象引用,它将保留在内存中。考虑

    # Inefficient memory usage
    import pandas as pd
    df_1 = pd.read_csv('first.csv')
    df_2 = pd.read_csv('second.csv')
    do_something(df_1)
    do_something(df_2)
    df_1.to_csv('output1.csv')
    df_2.to_csv('output2.csv')
    # Efficient memory usage
    df_1 = pd.read_csv('first.csv')
    do_something(df_1)
    df_1.to_csv('output1.csv')    # Last reference to df_1. dropped from memory here
    df_2 = read_csv('second.csv')   # Only df_2 in memory now
    do_something(df_2)
    df_2.to_csv('output2.csv')
    
    换句话说,要问自己的一个关键问题是“我的数据中有多少需要同时存储在内存中,或者我可以将问题分解为多个独立的问题”,然后您可以批量处理以提高内存效率

    在一个位置加载大型对象是可以的,但我认为没有必要提高效率。您只需要确保没有在一个循环中多次加载任何内容(例如,反复执行同一个SQL查询)。将其放在模块级别,或者如果您正在使用类,则在初始化时执行


    我通常的管道是,我有一个输入/输出层、一个转换层和一个控制器。控制器通常在早期调用文件,然后将其转发以进行处理。但是我所做的工作通常是同步的,所以我可以很容易地让一个控制器知道发生了什么。如果您有一个异步项目,那么正如您所说,这个管道可能会失控。我认为只有一个文件来处理上传是相当普遍的。但是,正如前面所解释的,它甚至可能没有必要,只要确保它发生在模块级别或类的初始化阶段

    请看,python解释器不一定在文件加载后重新加载。酷!那么,第二种方法是一种很好的实践吗?我提供这个链接是为了提供背景信息。在任何编程语言中,在代码中包含大量数据块都不是一种好的做法。数据应该与代码分开。尽管如此,我还是更喜欢你的第二种方式(以防有人问我哪种方式不那么糟糕)。
    from nltk.corpus import words
    WORDS = frozenset(words.words())   # Only gets executed once
    def check_word(word):
        return word in WORDS
    
    # Inefficient memory usage
    import pandas as pd
    df_1 = pd.read_csv('first.csv')
    df_2 = pd.read_csv('second.csv')
    do_something(df_1)
    do_something(df_2)
    df_1.to_csv('output1.csv')
    df_2.to_csv('output2.csv')
    # Efficient memory usage
    df_1 = pd.read_csv('first.csv')
    do_something(df_1)
    df_1.to_csv('output1.csv')    # Last reference to df_1. dropped from memory here
    df_2 = read_csv('second.csv')   # Only df_2 in memory now
    do_something(df_2)
    df_2.to_csv('output2.csv')