Сохранение объекта в локальной файловой системе или в S3 - PullRequest
0 голосов
/ 28 августа 2018

Мне нужен метод, который сохраняет объект (модель) в локальной файловой системе или в сегменте 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 голосов
/ 30 августа 2018

Да, нет ... обычно вам нужно закрыть файл после того, как вы записали (сбросили) в него свой контент. Когда вы используете с оператором , Python позаботится об этом. Если вы пропустите с, вам нужно использовать 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...