将对象坚持到本地文件系统或S3

时间:2018-08-28 08:46:07

标签: python amazon-s3

我需要一种将对象(模型)持久保存到本地文件系统或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)

我的问题是第二版本是否可以安全使用?

1 个答案:

答案 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)