Я пытаюсь обновить код, написанный на python2, так что он работает в python3 и все еще работает в python2. Это фрагмент кода в вопросе, который работает под python2:Объединение байтов для создания ctypes.c_char_p строки
import ctypes
import struct
class Ethernet(ctypes.Structure):
_fields_ = [('dst', ctypes.c_char_p)]
def __init__(self, packet):
(dst,) = struct.unpack('!6s', packet[:6])
self.dst = ':'.join(['%02x' % (ord(octet),) for octet in dst])
def main():
p = b'\xab\xad\xba\xbe\x0f\xe9'
e = Ethernet(p)
if b"ab:ad:ba:be:0f:e9" == e.dst:
print(True)
else:
print(False)
if __name__ == '__main__':
main()
Мои проблемы начинаются, когда я перехожу к Python3 я получаю это предупреждение для того же кода:
File "test2.py", line 11, in <listcomp>
self.dst = ':'.join(['%02x' % (ord(octet),) for octet in dst])
TypeError: ord() expected string of length 1, but int found
Так, очевидно, этот код не работайте так же, как в python3.
Единственный способ, которым я могу показаться, чтобы заставить его работать, как это:
try: # Python 3
self.dst = b':'.join([struct.pack('bb', ord('{:x}'.format((octet >> 4) & 0xf)), ord('{:x}'.format((octet >> 0) & 0xf))) for octet in dst])
except TypeError: # Python 2
self.dst = ':'.join(['%02x' % (ord(octet),) for octet in dst])
Что очень грязный, но каждый, каким образом я пытаюсь это НЕГО полей определение ctypes.c_char_p, что блоки ничего простого.
Есть ли лучший способ сделать это, что одна строка, которая работает как в python2 и Python3 (исключения не требуется)
2.6+ имеет ' bytearray', который повторяется как целые числа. У этого также есть 'b''' литералы. Для части форматирования в Python 3 вы можете использовать строку, а затем закодировать ее, что безвредно для Python 2. Например: 'dst = bytearray (пакет [: 6]);' 'self.dst = b ':'. join ([('% 02x'% октет) .encode ('ascii') для октета в dst]) ' – eryksun
Казалось, что он делает работу, намного чище и хорошо играет между python2 и python3. Спасибо за это, я не понимаю, как я отмечаю это как ответ. –
Форматирование 'bytes' является общей проблемой в Python 3. Вы искали ранее ответившие вопросы? BTW, в 3.5 'b '% 02x'% n', наконец, реализовано (т. Е. Определено« bytes .__ mod__ »). – eryksun