Python 2 到 Python 3 [英] Python 2 to python 3
问题描述
将这两种方法从 python2 转换为 python3 时遇到了一些麻烦.
Having some trouble translating these two methods from python2 to python3.
Python2:
def send(self, data):
if self.debug:
print 'Send:',
print ':'.join('%02x' % ord(c) for c in data)
l0 = len(data) & 0xFF
l1 = (len(data) >> 8) & 0xFF
d = chr(l0) + chr(l1) + data
self.sock.send(d)
def recv(self):
data = self.sock.recv(2)
l0 = ord(data[0])
l1 = ord(data[1])
plen = l0 + (l1 << 8)
data = self.sock.recv(plen)
if self.debug:
print 'Recv:',
print ':'.join('%02x' % ord(c) for c in data)
return data
Python 3 这是我目前得到的:
Python 3 This what I got so far :
def send(self, data):
if self.debug:
print('Send:', end=' ')
print(':'.join('%02x' % ord(c) for c in data))
l0 = len(data.encode('utf-8')) & 0xFF
l1 = (len(data.encode('utf-8')) >> 8) & 0xFF
d = chr(l0) + chr(l1) + data
self.sock.send(d)
def recv(self):
data = self.sock.recv(2)
l0 = ord(data[0])
l1 = ord(data[1])
plen = l0 + (l1 << 8)
data = self.sock.recv(plen)
if self.debug:
print('Recv:', end=' ')
print(':'.join('%02x' % ord(c) for c in data))
return data
我不断收到此错误:
TypeError: ord() expected string of length 1, but int found
任何帮助将不胜感激.谢谢
Any help would be appreciated. Thank you
推荐答案
要使您的代码在 Python 3 中工作,您需要解决两种主要类型的问题.
There are two main types of issues you need to address to make your code work in Python 3.
最大的问题是字符串和字节在 Python 3 中不再由相同的类型表示.str
类型用于 Unicode 字符串,bytes
类型用于二进制数据.您的 data
参数看起来应该是 bytes
(因为您直接在套接字上发送它).如果您确实想支持 Unicode 字符串,则需要在通过套接字发送它们之前用某种编码(例如 "UTF-8"
)对它们进行 encode()
.
The biggest issue is that strings and bytes are no longer represented by the same types in Python 3. The str
type is for Unicode strings, the bytes
type is for binary data. Your data
argument looks like it should probably be bytes
(since you're sending it directly out on a socket). If you did want to support Unicode strings, you'd need to encode()
them with some encoding (e.g. "UTF-8"
) before sending them over the socket.
无论如何,假设 data
是一个 bytes
实例,您需要对代码进行一些小的更改以解决一些 API 对 str
和 bytes
:
Anyway, assuming data
is a bytes
instance, you'll need to make a few small changes to the code to address how a few APIs work different for str
and bytes
:
对
bytes
进行迭代会产生单个字节值,但作为整数,而不是作为一个字符的字节串.这基本上意味着您不需要ord
在print
调用中,也不需要recv
的第一部分.
Iterating on a
bytes
yields the individual byte values, but as integers, not as one-character bytestrings. This basically means you don't need theord
in theprint
calls, nor in the first parts ofrecv
.
chr
函数创建一个 str
,而不是一个 bytes
实例,并且您不能将不同的类型连接在一起.从整数创建 bytes
实例有点笨拙(bytes(some_number)
不能满足您的要求),但这是可能的.
The chr
function creates a str
, not a bytes
instance, and you can't concatenate the different types together. Creating a bytes
instance from an integer is a bit awkward (bytes(some_number)
doesn't do what you want), but it is possible.
您遇到的另一个问题更容易理解.在 Python 3 中,print
是一个函数而不是一个语句,所以你需要将它的参数括起来.它还使用不同的语法来抑制行尾.
The other issue you have is much simpler to understand. In Python 3, print
is a function rather than a statement, so you need parentheses around its arguments. It also uses different syntax to suppress line endings.
这是您的代码的完全固定版本:
Here's a fully fixed version of your code:
def send(self, data):
if self.debug:
print('Send:', end='') # new way to suppress the newline
print(':'.join('%02x' % c for c in data)) # add parentheses, no need for ord
l0 = len(data) & 0xFF
l1 = (len(data) >> 8) & 0xFF
d = bytes([l0, l1]) + data # build prefix bytestring differently
self.sock.send(d)
def recv(self):
l0, l1 = self.sock.recv(2) # no need for ord, unpack directly as ints
plen = l0 + (l1 << 8)
data = self.sock.recv(plen)
if self.debug:
print('Recv:', end='')
print(':'.join('%02x' % c for c in data))
return data
请注意,struct
模块可能会提供一种更优雅的方式将数据长度编码和解码为字节串.例如,struct.pack("<H", len(data))
可以替换 send
中的几行代码(你不需要 l0
和 l1
).
Note that the struct
module may offer a more elegant way of encoding and decoding the length of your data to a bytestring. For instance, struct.pack("<H", len(data))
could replace several lines of the code in send
(you wouldn't need l0
and l1
).
这篇关于Python 2 到 Python 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!