2014-01-30 4 views
1

Я использую переменную для хранения данных, которые отправляются сокетом. Когда я назначаю его в своей программе, он работает, но когда я читаю его из файла, он рассматривается как строка.Назначение переменной шестнадцатеричного Python

Пример:

data = '\x31\x32\x33' 

print data 

Выходы

123 # <--- this is the result I want when I read from a file to assign data 


f = open('datafile') <--- datafile contains \x31\x32\x33 on one line 

data = f.readline() 

print data 

Выходы

\x31\x32\x33 # <--- wanted it to print 123, not \x31\x32\x33. 
+0

Как сохранить данные в файле. Кроме того, что он говорит, когда вы делаете «len (data)»? –

+0

Кажется, вы создали файл, содержащий 6 символов, а не 3 байта, как вы ожидали. –

+0

Вы не должны ** использовать его, но 'print (eval (" '"+ data +"' "))' будет делать это. – Sinkingpoint

ответ

2

В Python строка '\x31\x32\x33' на самом деле только три символа '\x31' есть символ с порядковым 0x31 (49), так что '\x31' эквивалентен '1'. Похоже, что ваш файл на самом деле содержит 12 символов \x31\x32\x33, что эквивалентно строке Python '\\x31\\x32\\x33', где экранированные обратные косые черты представляют собой один символ обратной косой черты (это также может быть представлено строковым литералом r'\x31\x32\x33').

Если вы действительно уверены, что эти данные должны быть '123', вам необходимо посмотреть, как этот файл записывается. Если это то, что вы можете контролировать, тогда вы должны обратиться к нему туда, чтобы в итоге не было данных, состоящих из нескольких байтов, представляющих шестнадцатеричные escape-последовательности.

Возможно также, что все, что записывает эти данные, уже использует некоторый формат обмена данными (аналогично JSON), и в этом случае вам не нужно изменять способ его написания, вам просто нужно использовать декодер для этого формата обмена данными (например, json.loads(), но это не JSON).

Если как-то ни один из выше действительно то, что вы хотите, и вы просто хотите, чтобы выяснить, как преобразовать строку как r'\x31\x32\x33' в '123' в Python, вот как вы можете это сделать:

>>> r'\x31\x32\x33'.decode('string_escape') 
'123' 

Или на Python 3.х:

>>> br'\x31\x32\x33'.decode('unicode_escape') 
'123' 

редактировать: Основываясь на комментариях, похоже, вы фактически получаете шестнадцатеричные строки, как '313233', чтобы преобразовать строку типа, что '123' можно расшифровать с помощью шестигранного:

>>> '313233'.decode('hex') 
'123' 

Или на Python 3.x:

>>> bytes.fromhex('313233').decode('utf-8') 
'123' 
+0

Спасибо! Я могу контролировать, как файл отформатирован, поэтому я удалил все \ x и использовал декодирование. Это сделал трюк. – user3254700

0

Да, когда вы делаете преобразование из строки в междунар, вы можете указать базу номера в строке:

>>> print int("31", 16) 
49 

>>> chr(49) 
'1' 

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

+0

Это одноэтапное преобразование не работает. Просто распечатайте x после его назначения, и вы увидите строку «123AU». Разделение его на подстроку, которая не встречается, приведет к созданию списка, содержащего только исходную строку. – krait

+0

Да, если вы назначаете x = r "\ x31 \ x32 \ x33 \ x41 \ x55", что эквивалентно тому, что он читает, это не работает. – jbh

0

Как указано вы делаете постобработки, было бы легче справиться, если текст был «313233» вы бы тогда быть в состоянии использовать

data = "313233"  
print data.decode("hex") # this will print '123' 

Как указано в комментариях это для Python 2.7, и устарел в 3.3. Однако, если этот вопрос не указан неправильно, это будет работать.

+0

Декодирование ('hex') устарело и удалено на Python3 – JBernardo

+0

он крикнул, что использует python 2.7 в своих тегах – jbh

0

я бы нарушил многие стандарты программирования здесь, но следующий код работает для данной ситуации

with open('datafile') as f: 
    data=f.read() 
data=data.lstrip('\\x') #strips the leftmost '\x' so that now string 'data' contains numbers saperated by '\x' 
data=data.strip().split('\\x') #now data contains list of numbers 
s='' 
for d in data: 
    s+=chr(int(d,16)) #this converts hex ascii values to respective characters and concatenate to 's' 
print s 
Смежные вопросы