【问题标题】:String from list of bytes?字节列表中的字符串?
【发布时间】:2020-01-08 22:07:37
【问题描述】:

尝试将 python 列表转换为字符串非常沮丧,但它不断将单个字节转换为 3 字节对象。

我的代码从 i2c 连接获取字节并将它们存储在列表中。它应该通过网络将它们作为字符串对象发送,它会这样做。然而,在我的计算机的 java 端,一个单字节(例如 254)实际上是

00110010 
00110101
00110100 

而不是11111110

请指教?

在转换之前,我将数组打印到我的屏幕上:

print("outgoing")
print(outgoing)

这是打印屏幕的结果:

outgoing
[254, 5, 0, 255, 255, 255, 255, 255, 255, 255, 254, 0, 202]

我尝试将列表转换为单个字符串,如下所示:

st = ''
try:
    for e in outgoing:
        st += str(e)
except:
    e = sys.exc_info()[0]
    print(e)
print(st)

我尝试了多种其他方式来转换它。 我写入网络的方法需要一个字符串对象,否则一切正常。

【问题讨论】:

  • ''.join(str(e) for e in 传出)
  • ''.join([chr(b) for b in outgoing])?此外,查看struct 模块以进行更复杂的二进制数据操作。看起来你不需要 Unicode 表示,所以你可以试试struct.pack
  • 这是 Python 2 还是 3?我觉得奇怪的是,您写入网络的方法会采用 str 对象,在 Python 3 中,它是一个 unicode 代码点序列......它采用 字节序列,即 Python 2 str 或 Python 3 bytes 对象...
  • 我试过上面的两个 cmets 都没有运气。仍然要研究结构模块。 pi 上的 2.7 版。我相信我可以重写一堆其他方法来使用字节列表,但似乎应该有一种方法可以将字节连接在一起。
  • @cagney 好的,当您使用 Python 2 时,您真的应该指出,请注意,它不再受到官方支持,并且已通过它的官方生命周期结束。当涉及到字符串/字节时,这是 Python 2 和 3 之间非常重要的区别。

标签: python string python-2.7 byte python-2.x


【解决方案1】:

这是您的问题:您将这些数字的字符串表示形式连接在一起,而不是字节本身。 Python 2 中可能有更好的方法,但是:st = str(bytearray(outgoing)) 应该可以工作......哎呀,bytearray(outgoing) 可能会自己工作。

所以,要明确的是,您所做的基本上是:

>>> outgoing = [254, 5, 0, 255, 255, 255, 255, 255, 255, 255, 254, 0, 202]
>>> st = ''.join(map(str, outgoing))
>>> st
'254502552552552552552552552540202'

但这不是你想要的,你想要的:

>>> str(bytearray(outgoing))
'\xfe\x05\x00\xff\xff\xff\xff\xff\xff\xff\xfe\x00\xca'

虽然,正如我所说,取决于您使用的任何客户端,

>>> bytearray(outgoing)
bytearray(b'\xfe\x05\x00\xff\xff\xff\xff\xff\xff\xff\xfe\x00\xca')

可能就足够了。

注意,如果有人在 Python 3 上遇到类似情况,那么您只需:

>>> outgoing = [254, 5, 0, 255, 255, 255, 255, 255, 255, 255, 254, 0, 202]
>>> bytes(outgoing)
b'\xfe\x05\x00\xff\xff\xff\xff\xff\xff\xff\xfe\x00\xca'

【讨论】:

  • 感谢您的回复。答案不适用于我的情况,为了测试最后一个答案,我将我的 pi 升级到 py3。然而,这破坏了一堆其他代码。由于我不是真正的 python 专家,我回到单元测试每个方法。生病后在这里发布结果。虽然不确定它们在那时的相关性如何
  • @cagney 什么不适用于 Python 2 解决方案?
  • 昨天我在墙上扔东西,没有记录我的结果。对不起。我事后的评估是我可能有一个混合类型的对象列表。更多内容见帖子
【解决方案2】:

python 很糟糕,感觉就像一个没有饼干的蹒跚学步的孩子,我有两个选择。

一种方法是在 python 中使用附加前缀零的字符串来使 python 给我的字符串表示形式在我的其他代码中工作。

第二个是在python代码中创建这个讽刺,如下所示。感谢您的建议,因为我确实将我的 pi 升级到了 py3,它引导我朝着正确的方向前进。

如您所见,我使用 pybluez 和 smbus2 来促进数据传输。如果有更好的例子,我当然不介意看到它。

def move_data(bus, incoming):
if not incoming:
    return ""
#print('incoming')
#print(incoming)
readfail = 1
add = b'\x00'
adloc = 0
data = []
outgoing = []
outgoing.append(b'\xfe')
info = [incoming[i:i+1] for i in range(0, len(incoming), 1)]
#print(info)
for s in info:
    #print(s)
    i = struct.unpack('<c', s)
    #print(i[0])
    if i[0] == b'\xfe':
        #print("254")
        if add != b'\x00':
            #print("add")
            if len(data) > 0:
                #print("send data")
                #print(add)
                #print(data)
                write_slave(bus, add, data)
                print("sent")
                outgoing.append(add)
                while readfail == 1:
                    try:
                        print("stuck")
                        time.sleep(.005)
                        addlist = list(add)
                        var = read_slave(bus, addlist[0], 8)
                        print("stuck---")
                        readfail = 0

                    except:
                        pass

                print("return data")
                print(var)
                now = bytes(var)
                print(now)
                rtn = [now[i:i + 1] for i in range(0, len(now), 1)]
                for e in rtn:
                    q = struct.unpack('<c', e)
                    outgoing.append(q[0])
                outgoing.append(b'\xfe')
            readfail = 1
            add = b'\x00'
            del data[:]
        else:
            adloc = 1
    elif adloc == 1:
        add = i[0]
        adloc = 0
        #print("added add")
    else:
        data.append(i[0])
        #print("added data")
outgoing.append(add)
outgoing.append(data[0])

    #ad = mlist
    #if ad != 0:
        #if s != '':
            #write_slave(bus, ad, s[2:])update to python 3
        #fromParts += ad
        #fromParts += read_slave(bus, ad, s[2:].len())
        #fromParts += b'fe'
#print_string(out)
print("outgoing")
print(outgoing)

#st = ''.join([chr(b) for b in outgoing])

#st = bytearray(outgoing)

#st = b''
#try:
    #for e in outgoing:
        #if e < 100:
            #st += '0'
            #if e < 10:
                #st += '0'
        #st += str(e)
#except:
    #e = sys.exc_info()[0]
   # print(e)
st = b''.join(outgoing)
#print(st)
return st

这里是我寄来写的……别笑

def write_slave(bus, add, data):
st = b''.join(data)
datlist = list(st)
addlist = list(add)

bus.write_i2c_block_data(addlist[0], cmdReq, datlist)

【讨论】:

    猜你喜欢
    • 2014-11-08
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2018-07-23
    • 2021-06-23
    相关资源
    最近更新 更多