python3报错TypeError: ord() expected string of length 1, but int found.

问题

将这两种方法从python2转换为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:

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

解决方法

要使代码在Python 3中工作,需要解决两种主要类型的问题。

最大的问题是字符串和字节不再由Python 3中的相同类型表示str类型用于Unicode字符串, bytes类型用于二进制数据。 您的data参数看起来可能应该是bytes (因为您是直接在套接字上发送它的)。 如果确实要支持Unicode字符串,则需要通过某种编码(例如"UTF-8" ) encode()它们进行编码(),然后再通过套接字发送它们。

无论如何,假设data是一个bytes实例,则需要对代码进行一些小的更改,以解决一些API对于str和bytes不同工作方式:

对bytes迭代会产生各个字节的值,但会产生一个整数,而不是一个字符的字符串。 这基本上意味着您不需要在print调用中使用ord ,也不需要在recv的第一部分中使用ord 。

chr函数创建一个str而不是一个bytes实例,并且您不能将不同的类型连接在一起。 从整数创建一个bytes实例有点尴尬( bytes(some_number)不能满足您的要求),但是有可能。

您遇到的另一个问题更容易理解。 在Python 3中, print是函数而不是语句,因此您需要在其参数周围加上括号。 它还使用不同的语法来抑制行尾。

这是解决的代码:

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 )。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是空空呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值