python - 将大对象加载到一个文件中并将它们导入其他 Python 文件是一种好习惯吗?
问题描述
我最近意识到,在一个 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_huge_file_i()。
另外,您还有其他建议吗?
解决方案
几个考虑。因此,首先,文件中的任何内容都将在导入文件时执行,通常是立即执行。所以我经常在我的文件中预先加载。但它不必在一个位置。您可以在许多不同的文件中执行此操作。例如:
减缓:
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 查询)。将其放在模块级别,或者如果您使用的是类,则在初始化时进行。
我通常的管道是我有一个输入/输出层、一个转换层和一个控制器。控制器通常在早期调用文件,然后转发它们以进行处理。但是我所做的工作通常是同步的,所以我可以很容易地让控制器知道发生了什么。如果您有一个异步项目,那么正如您所说,这个管道可能会失控。我认为拥有一个文件来处理上传是相当普遍的。但正如解释的那样,它甚至可能没有必要,只需确保它发生在模块级别或类的初始化时。
推荐阅读
- python - RSA 验证 python、python-rsa 库中的 p 和 q 密钥
- javascript - 如何在作为对象属性值的数组上使用javascript reduce方法并仅输出正元素的总和?
- node.js - 如何解决 React:创建 webapp 时出现“编译失败;./src/App.js”错误
- reactjs - React Hooks 首先在 Websockets 中发送消息
- html - 为什么每次我重新刷新我的网站 html5 音频时自动播放都不起作用
- python - pyrogram send_audio 抛出 TypeError
- c++ - 如何防止 gdb 中循环引用的堆栈溢出
- windows - 在新的颤振和飞镖版本上运行旧代码
- javascript - 如何使用谷歌标签管理器删除 magento 默认模式标记?
- .net - 与版本 5 包一起安装 dotnet 6 preview 6 RPM 包