连接字节以创建ctypes.c_char_p字符串

时间:2015-07-16 13:59:32

标签: python python-3.x ctypes

我正在尝试升级一些用python2编写的代码,因此它可以在python3中运行并且仍然可以在python2中运行。这是在python2下运行的代码片段:

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的 fields 定义阻止任何简单的事情。

有没有更好的方法可以在python2和python3中运行单行(不需要例外)

1 个答案:

答案 0 :(得分:0)

我不知道为什么我不能标记正确答案,但eryksun回复对我有用:

2.6+具有bytearray类型,它以整数形式迭代。它还有b''个文字。对于Python 3中的格式化部分,您可以使用字符串然后对其进行编码,这在Python 2中是无害的。例如:

dst = bytearray(packet[:6]); 
self.dst = b':'.join([('%02x' % o).encode('ascii') for o in dst])` 

- eryksun 7月16日15:39