Ошибка типа: невозможно объединить байты в int

#python

#python

Вопрос:

Я пытаюсь хэшировать имя файла, а затем сохранить в БД. Я использую Flask и Python 3.4

Это код для загрузки:

 @app.route('/', methods=['GET', 'POST'])
def upload_pic():
    if request.method == 'POST':
        file = request.files['file']
        try:
            extension = file.filename.rsplit('.', 1)[1].lower()
        except IndexError as e:
            abort(404)
        if file and check_extension(extension):
            # Salt and hash the file contents
            filename = md5(file.read()   str(round(time.time() * 1000))).hexdigest()   '.'   extension
            file.seek(0)  # Move cursor back to beginning so we can write to disk
            file.save(os.path.join(app.config['UPLOAD_DIR'], filename))
            add_pic(filename)
            gen_thumbnail(filename)
            return redirect(url_for('show_pic', filename=filename))
        else:  # Bad file extension
            abort(404)
    else:
        return render_template('upload.html')
 

Когда я отправляю форму, я получаю обратную трассировку ошибки.

 Traceback (most recent call last):
  File "C:Python34libsite-packagesflaskapp.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:Python34libsite-packagesflaskapp.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "C:Python34libsite-packagesflaskapp.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:Python34libsite-packagesflask_compat.py", line 33, in reraise
    raise value
  File "C:Python34libsite-packagesflaskapp.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "C:Python34libsite-packagesflaskapp.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:Python34libsite-packagesflaskapp.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:Python34libsite-packagesflask_compat.py", line 33, in reraise
    raise value
  File "C:Python34libsite-packagesflaskapp.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:Python34libsite-packagesflaskapp.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:UsersAjayPycharmProjectscodehackr-uploadflaskgur.py", line 70, in upload_pic
    filename = md5(file.read()   (round(time.time() * 1000))).hexdigest()   '.'   extension
TypeError: can't concat bytes to int
 

Я не знаю, что происходит не так, пожалуйста, просветите меня.

Спасибо.

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

1. Ваша трассировка не соответствует коду. Код уже исправлен, но трассировка показывает, что вы используете другой код.

Ответ №1:

Вы пытаетесь объединить результат file.read() с результатом round(time.time() * 1000)) , который является целым числом. Вот почему вы получаете ошибку:

 TypeError: can't concat bytes to int
 

Попробуйте привести целое число:

 file.read()   bytes(round(time.time() * 1000)))
 

Но, как заметил @Lev Levitsky, похоже, что в вашем коде уже есть исправление: вы уверены, что запускаете последнюю версию своего кода?

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

1. Не было бы более уместным преобразовать его в bytes type?

2. Ты прав! Не знаю, почему я допустил эту ошибку 🙂

Ответ №2:

Да, как писал julienc, проблема заключалась в попытке объединить результат file.read() , типа bytes , с результатом round(time.time() * 1000)) , который был an int .

НО НЕ ДЕЛАЙТЕ ТОГО, ЧТО ПОКАЗАНО В ДРУГОМ ОТВЕТЕ! Сохраняйте спокойствие и продолжайте читать…

Как создать байты в Python 3

 # (1)
bytes(12)                == b'x00x00x00x00x00x00x00x00x00x00x00x00'

# (2)
bytes([12])              == b'x0c'
bytes([444])             -> ValueError("bytes must be in range(0, 256)")
bytes([0x01, 0xBC])      == b'x01xbc'

# (3)
( 12).to_bytes(8, 'big') == b'x00x00x00x00x00x00x00x0c'
(444).to_bytes(8, 'big') == b'x00x00x00x00x00x00x01xbc'

# (4)
str(12).encode('utf8')   == b'12'
 

(1) Создать bytes длину n , которая пуста (заполнена нулями)

Это редко то, что вы хотите. Осторожно!

В контексте этого вопроса md5(file.read() str(round(time.time() * 1000))) хэшируется содержимое файла, а затем около 1,5 триллионов пустых байтов. Технически он все еще делает то, что нужно, но тьфу, за какие вычислительные затраты 🙂

(2) Создать bytes длину, n содержащую указанные значения

Каждое исходное значение должно быть от 0 до 255, чтобы поместиться в байт.

Конечно, можно было бы также записать с помощью кортежа, но это немного уродливее для случая длины 1: bytes((12,))

(3) Создать bytes как собственное / двоичное представление целого числа

Это ответ на исходный вопрос, как преобразовать целое число в поток и т. Д.

Но теперь вам нужно подумать о некоторых низкоуровневых вещах, таких как количество байтов вывода и порядковый номер (порядок байтов). Подробности см. в int.to_bytes() документах.

Конечно, дополнительные круглые скобки необходимы только для буквального значения 12 в этом примере. Они могут быть опущены при использовании переменной или другого выражения.

(4) Создайте байты из указанного текста ( str ).

В качестве альтернативы вышесказанному, иногда вам не нужно или не хочется думать о низкоуровневых соображениях, и тогда та же цель может быть достигнута простым хешированием (или чем угодно) простого текстового представления значения человеком.

Конечно, 'ascii' или что-то еще можно было бы использовать вместо 'utf8' этого в этом примере. Но почему бы не тренировать мышечную память с помощью того, что вы хотите почти повсеместно в любом другом месте?