我需要一种将对象(模型)持久保存到本地文件系统或S3存储桶的方法。目的地由环境变量MODELS_DIR
确定。我有两个版本,第一个版本更长一些,我对它的正确性很有信心。第二个版本较短,但我担心不使用with
语句实际上是错误的。
def persist_model(model, model_name):
""" VERSION 1
Persist `model` under the name `model_name` to the environment variable
`MODELS_DIR` (having a trailing '/').
"""
MODELS_DIR = os.getenv('MODELS_DIR')
if MODELS_DIR.startswith('s3://'):
s3 = s3fs.S3FileSystem()
with s3.open(MODELS_DIR[5:] + model_name, 'wb') as f:
joblib.dump(model, f)
else:
with open(MODELS_DIR + model_name, 'wb') as f:
joblib.dump(model, f)
和:
def persist_model(model, model_name):
"""VERSION 2
Persist `model` under the name `model_name` to the environment variable
`MODELS_DIR` (having a trailing '/').
"""
MODELS_DIR = os.getenv('MODELS_DIR')
if MODELS_DIR.startswith('s3://'):
s3 = s3fs.S3FileSystem()
f = s3.open(MODELS_DIR[5:] + model_name, 'wb')
else:
f = open(MODELS_DIR + model_name, 'wb')
joblib.dump(model, f)
我的问题是第二版本是否可以安全使用?
答案 0 :(得分:1)
是否...通常,您在写入(转储)内容后需要关闭该文件。 当您使用 with 语句时,Python会注意这一点。如果跳过with,则需要使用 f.close() 或 s.close() 。
此外,要确保即使在发生错误的情况下也能关闭文件,您将需要使用try-finally构造。因此,如果正确使用第二个版本,它将比第一个更长。
如果您想避免代码重复,我建议使用函数选择器:
def persist_model(model, model_name):
def get_file_opener(path):
if path.startswith('s3://'):
return s3fs.S3FileSystem().open
else
return open
full_path = os.getenv('MODELS_DIR')
with get_file_opener(fullpath)(fullpath[5:] + model_name, 'wb') as f:
joblib.dump(model, f)