首页 > 解决方案 > 将大对象加载到一个文件中并将它们导入其他 Python 文件是一种好习惯吗?

问题描述

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

看来我有两个选择:

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

  2. 将所有大对象加载到一个文件中,并在项目中的任何 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_huge_file_i()。

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

标签: pythonimport

解决方案


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

减缓:

from nltk.corpus import words

def check_word(word):
    return word in words.words():    # gets executed on every call

快速地:

from nltk.corpus import words
WORDS = frozenset(words.words())   # Only gets executed once
def check_word(word):
    return word in WORDS

然而,另一个考虑因素是内存。如果您尽早将大量对象加载到内存中,即使它们不被使用,您也会随身携带它们。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 查询)。将其放在模块级别,或者如果您使用的是类,则在初始化时进行。

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


推荐阅读