Как закрыть файл, который открыт для чтения при вызове API

#python #json #api

#python #json #API

Вопрос:

 import glob
import os
import requests
import shutil


class file_service:
    
    def file():
        dir_name = '/Users/TEST/Downloads/TU'
        os.chdir(dir_name)

        pattern='TU_*.csv'

        for x in glob.glob(pattern):
            file_name=os.path.join(dir_name,x)
            print (file_name)
        from datetime import date
        dir_name_backup = '/Users/Zill/Downloads/backup'
        today = date.today()
        backup_file_name = f'Backup_TU_{today.year}{today.month:02}{today.day:02}.csv'
        backup_file_name_directory= os.path.join(dir_name_backup,backup_file_name)
        print(backup_file_name_directory)
        newPath = shutil.copy(file_name, backup_file_name_directory)
        url = "google.com"

        payload = {'name': 'file'}
        files = [
        ('file', open(file_name,'rb'))
        
        ]
        headers = {
        'X-API-TOKEN': '12312'
        }

        response = requests.request("POST", url, headers=headers, data = payload, files = files)

        print(response.text.encode('utf8'))
        
        files.close()
        os.remove(file_name)


    file()
  

Чтобы обеспечить общий контекст, я пытаюсь извлечь файл из своей ОС и, используя метод POST, я пытаюсь опубликовать содержимое файла в приложении. Пока все работает так, как ожидалось, детали передаются в приложение, как и ожидалось. В рамках моего следующего шага я пытаюсь удалить файл из существующего каталога с помощью os.remove(). Но я получаю ошибку Win32, поскольку мой файл не закрыт, когда он был открыт в режиме только для чтения при вызове POST. Я пытаюсь закрыть его, но не могу этого сделать.

Может кто-нибудь, пожалуйста, помогите мне с этим.

Спасибо!

Комментарии:

1. Вы пытаетесь использовать with оператор типа with open(file_name) as f:

2. @general03 можем ли мы использовать оператор with в JSON? Я этого раньше не делал. Не могли бы вы подробнее рассказать

3. Я немного в замешательстве: что files.close() именно делать?

4. @Timus это помогает закрыть файл, который был открыт для чтения. К сожалению, мой вызов API открывает файл в самом массиве JSON, из-за чего я не могу его закрыть.

5. Разве open(file_name,'rb') в понимании списка fd нет s для последующего закрытия?

Ответ №1:

Я не уверен, что правильно понимаю ваш код. Не могли бы вы попробовать заменить

 files.close()
  

с помощью

 for _, file in files:
    file.close()
  

и проверить, работает ли он?

Объяснение: В

  files = [('file', open(file_name,'rb'))]
  

вы создаете список, содержащий ровно один кортеж, который имеет строку 'file' в качестве первого элемента и file объект в качестве второго элемента:

 [('file', file_object)]
  

Цикл берет кортеж из списка, игнорирует его первый элемент ( _ ) , берет его второй элемент, file объект, и использует его close метод для его закрытия.

Я только сейчас понял, что список содержит только один кортеж. Так что нет необходимости в цикле:

 files[0][1].close()
  

должен это сделать.

Лучшим способом было бы использовать with (файл автоматически закрывается, как только вы покидаете with блок):

         payload = {'name': 'file'}
        with open(file_name, 'rb') as file:

            files = [('file', file)]
            headers = {'X-API-TOKEN': '12312'}
            response = requests.request("POST", url, headers=headers, data = payload, files = files)
            print(response.text.encode('utf8'))
        
        os.remove(file_name)
  

Комментарии:

1. Можете ли вы объяснить, что на самом деле делает ваш цикл for?

2. @AanuragDas Смотрите мою правку. Цикл на самом деле не нужен, поскольку список содержит только один элемент ( файлы звучали как больше файлов).