LINUX.ORG.RU

Ошибка в кодировке Python3. Фикс вызывает новую ошибку.

 


0

2

Код:

import subprocess 
mac = subprocess.Popen(['ifconfig', 'wls1'], stdout=subprocess.PIPE)
omac = mac.stdout.read()
a = (omac.find('H'))
print(a) 
__
Результат:

Traceback (most recent call last):
  File "mac.py", line 4, in <module>
    a = (omac.find('H'))
TypeError: 'str' does not support the buffer interface

Код после фикса:

import subprocess 
mac = subprocess.Popen(['ifconfig', 'wls1'], stdout=subprocess.PIPE)
omac = mac.stdout.read()
tmac = omac.encode('utf-8')
a = (tmac.find('H'))
print(a)
__
Результат:

raceback (most recent call last):
  File "mac.py", line 4, in <module>
    tmac = omac.encode('utf-8')
AttributeError: 'bytes' object has no attribute 'encode'

Привет, давно не виделись :-)

FIL ★★★★ ()
a = omac.find(b'H')

Также

Warning

Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

Не желаете читать доки - валите к чертям на пхп обратно, или откуда вы там вылезли, не понижайте общий уровень аудитории языка.

Deleted ()

У тебя специфичный масштаб задач
Я бы рекомендовал посмотреть в сторону sh

Пример из примера

from sh import ifconfig
print ifconfig("eth0")

zolden ★★★★★ ()
Ответ на: комментарий от exception13

а может сразу ansible?

и тут ты такой с наглядными примерами, красивыми конфигами, чоткими демками - бабах!
а мы такие - Ва-а-аах, краса-а-аава!

zolden ★★★★★ ()
Ответ на: комментарий от Deleted

Спасибо. Это мой первый язык, а английский знаю плохо, иначе меня бы тут не было.

То есть мы с помощью b переводим в байты? А почему второй вариант выдавал ошибку, надо было какой-то модуль импортировать?

kramh ()
Ответ на: комментарий от kramh

Тебе надо было делать decode, а не encode. Чтобы перевести из массива байт в utf-8 который вывела программа во внтуренний питоновский тип строки.

Вообще в таком простом скрипте проще было бы написать.

import os
omac = os.popen('ifconfig wls1').read()
pawnhearts ★★★★★ ()
Ответ на: комментарий от kramh

С помощью b-литерала мы создаем объект bytes.

У bytes нет encode, есть только decode. И именно он тебе и нужен был, если ты хотел перевести в str.

Deleted ()
Ответ на: комментарий от Deleted

Ага, разобрался уже.

Кстати, если делать в текстовике, то как раз будет эта ошибка и нужно будет делать декод; а если в vim, например, то все и так работает. __ Я это пишу, потому что может кто будет гуглить похожую ошибку и наткнется на это.

kramh ()
Ответ на: комментарий от exception13

Да, кстати. Пердолиться в шелле - зашквар по понятиям.

Deleted ()
Ответ на: комментарий от kramh

Нет, ошибся. Это не имеет значения

Декордировать в любом случае надо

kramh ()
Ответ на: комментарий от pawnhearts

Кстати, а почему именно в этом случае понадобилось декодирование?

a = "11 22 33 44 55 M 66"
print(a.find("M")) 

Это, например, исполняется без проблем.

kramh ()
Ответ на: комментарий от kramh

Ну оно stdout у подпроцесса в двоичном виде открывает. Оно же может тебе не только текст выводить, но и поток байт типа gzip какого-нить.

Если ты откроешь файл в режиме binary типа open('test', 'rb') - то что ты из него прочитаешь тоже надо будет декодировать, если ты хочешь как с текстом с этим работать.

pawnhearts ★★★★★ ()
Ответ на: комментарий от Deleted

У bytes нет encode, есть только decode. И именно он тебе и нужен был, если ты хотел перевести в str.

По-моему, проще писать

mystr = str(mybytes, 'KOI8-R') #UTF-8 по умолчанию
mybytes = bytes(mystr, 'KOI8-R')

proud_anon ★★★★★ ()
Последнее исправление: proud_anon (всего исправлений: 1)
Ответ на: комментарий от pawnhearts

То есть мы с помощью decode переводим двоичный код подпроцесса в юникод, чтобы он мог работать с нашей «Н» в юникоде?

А если написать (b'H'), то мы «Н» переводим в двоичный вид?

Т.е. в обоих случаях приводим их к одному виду, чтобы они могли друг с другом взаимодействовать. Правильно?

kramh ()
Ответ на: комментарий от kramh

b'H' — это литерал. Python на этапе парсинга скрипта подставляет объект bytes, полученный путём кодирования строки 'H' в UTF-8.

С помощью decode ты во время выполнения преобразуешь (заранее неизвестные) объекты bytes в str, декодируя их по UTF-8.

Ещё раз повторю, что, по моему мнению, проще писать tmac = str(omac)

Кроме того, ты мог передать конструктору Popen параметр universal_newlines=True, и тогда stdout.read() возвращал бы строки.

Кроме того, вместо subprocess.Popen ты мог бы вызвать subprocess.check_output или subprocess.run (в Python 3.5).

proud_anon ★★★★★ ()
Последнее исправление: proud_anon (всего исправлений: 1)
Ответ на: комментарий от kramh

Ну, в общем да.

Ты почитай книжку какую-нить, книги есть на русском, там всё это описано. Многие рекомендуют Лутца.

pawnhearts ★★★★★ ()
Ответ на: комментарий от proud_anon

Слушай, а если программа большая будет, то тогда, наверное, оправданней все в bytes переводить, а потом в UTF? Ну ладно, разберусь

kramh ()

Ошибка в ... Фикс вызывает новую ошибку

Добро пожаловать в увлекательный мир программирования.

Aswed ★★★★★ ()

По делу - ты путаешь encode и decode

Aswed ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.