将Python2.7>3.8 struct.Pack(“H”)查找为字符串以加入列表?

2024-09-28 05:20:04 发布

您现在位置:Python中文网/ 问答频道 /正文

这是。。一个长的。因此,对于代码和问题方面的任何不一致之处,我深表歉意。我一定会尽可能多地添加源代码,以确保问题尽可能清楚

目前正在进行的这个项目是将Python2转换为Python3的一次尝试,到目前为止,它还相当简单。我的同事和我已经到了一个地步,尽管谷歌搜索或搜索都没有给出一个直接的答案,所以我们到了


好吧,从

Python 2代码:

listBytes[102:104]=struct.pack('H',rotation_deg*100) # rotational position in degrees
listBytes[202:204]=struct.pack('H',rotation_deg*100) # rotational position in degrees
listBytes[302:304]=struct.pack('H',rotation_deg*100) # rotational position in degrees
# this continues on for a while in the same fashion

其中旋转度是介于0.00和359.99之间的浮动(但对于测试而言,几乎总是在150-250之间变化)

为了测试的目的,我们将使旋转度始终为150.00

a = listBytes[102:104]=struct.pack('H',150.00*100)
print a
print type(a)

以下文件的打印输出为:

�:
<type 'str'>

据我所知,在Python2版本的struct.pack中,它将浮点数打包为short,然后作为short“添加”到列表中。Python2将其视为一个字符串,不向该字符串添加任何编码(稍后将在Python3中讨论)。所有这些都很简单,很好,然后在列表中添加更多的内容,我们可以:

return ''.join(listBytes)

将其发送回一个简单变量:

bytes=self.UpdatePacket(bytes,statusIndex,rotation_deg,StatusIdList,StatusValueList, Stat,offsetUTC)

然后作为字符串发送到

sock.sendto(bytes , (host, port) )

这一切加在一起看起来是这样的: A string with a bunch of bytes (I think)

这是一个工作版本,在这个版本中,我们沿着套接字发送字节,检索数据,每个人都很高兴。如果我错过了什么,请让我知道,否则,让我们移动到


Python 3

This is where the Fun Begins

Python2和Python3之间需要立即进行一些更改

  1. struct.pack('H',rotation_deg*100)需要打包一个INT类型,这意味着必须为所有打包实例提供int(rotatin_deg*100)以避免程序出错
  2. sock.sendto(bytes, (host, port))不再工作,因为套接字需要一个bytes对象来发送某些内容。没有更多看起来像字节的字符串,它们必须正确编码才能正确发送。所以现在它变成了sock.sendto(bytes.encode(), (host, port))来正确地编码“bytes”字符串

作为背景,listBytes的长度应始终为1206。问题是,无论我们如何使用python 3代码,.join似乎发送的不仅仅是字节对象,通常是listBytes长度的五倍,并破坏socket.sendto

listBytes[102:104] = struct.pack('H', int(rotation_deg * 100))  # rotational position in degrees
listBytes[202:204] = struct.pack('H', int(rotation_deg * 100))  # rotational position in degrees
listBytes[302:304] = struct.pack('H', int(rotation_deg * 100))  # rotational position in degrees
# continues on in this fashion again
return ''.join(str(listBytes))

返回:

bytes = self.UpdatePacket(bytes, statusIndex, rotation_deg, StatusIdList, StatusValueList, Stat, offsetUTC)
sock.sendto(bytes.encode(), (host, port))

事情开始变得奇怪了

a = struct.pack('H', int(150.00 * 100))

返回: b'\x98:',其类型为<class 'bytes'>,这很好,是我们想要的值,只是我们特别需要将此变量作为字符串存储到列表中。。。稍后将其编码为作为套接字的字节对象发送

你开始看到问题了,是吗

问题是,我们尝试了几乎所有的技术,将struct.pack返回的两个字节转换成某种字符串,我们已经能够将其转换,但随后我们遇到了.join是邪恶的问题

还记得我说的listBytes必须保持1206的大小,否则它会崩溃吗?出于某种原因,如果我们.join实际上除了作为字符串的两个字节之外的任何东西,我们认为python试图添加一些我们不需要的其他东西

所以现在,我们将重点放在尝试将Python2等效于Python3

以下是我们尝试过的内容

binascii.hexlify(struct.pack('H', int(150.00 * 100))).decode()返回'983a'

str(struct.pack('H', int(150.00 * 100.00)).decode())返回一个错误,'utf-8' codec can't decode byte 0x98 in position 0: invalid start byte

str(struct.pack('H', int(150.00 * 100.00)).decode("utf-16"))返回'㪘'。我甚至无法理解这一点

return b''.join(listBytes)返回错误,因为列表开头有int

return ''.join(str(listBytes)).encode('utf-8')仍然在添加一些废话


现在我们进入.join,第一个循环似乎是。。好的在加入之前,它有1206个aslistBytes长度。但是在第二个循环中,它产生了大量垃圾,使得列表长度5503。第三次循环时,它变成了27487,最后一次循环时,它变得太大,套接字无法处理,我被[WinError 10040] A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself打了一巴掌


唷,如果你能走到这一步,谢谢你。任何帮助都将不胜感激。如果你有问题或者我遗漏了什么,请告诉我

谢谢


Tags: 字符串in字节bytespositionstructpackint
1条回答
网友
1楼 · 发布于 2024-09-28 05:20:04

你只是太努力了。考虑bytesunicode而不是模棱两可的str类型(前者在Python 2中,后者在Python 3中)可能会有所帮助struct始终生成bytes,并且socket需要发送bytes,无论语言版本如何。换言之,进程外部的所有内容都是字节,尽管有些表示系统其余部分选择的某些编码中的字符。字符是用于在程序中操作文本的数据类型,就像浮点数是用于操作“实数”的数据类型一样。这里没有字符,因此绝对不需要encode

因此,只需累积bytes对象,然后将它们与b''.join连接起来(如果不能直接使用片分配似乎正在写入的缓冲区),将它们作为字节保留

相关问题 更多 >

    热门问题