Python 2 到 Python 3 [英] Python 2 to python 3

查看:34
本文介绍了Python 2 到 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 对 strbytes:

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:

  1. bytes 进行迭代会产生单个字节值,但作为整数,而不是作为一个字符的字节串.这基本上意味着您不需要 ordprint 调用中,也不需要 recv 的第一部分.

  1. Iterating on a bytes yields the individual byte values, but as integers, not as one-character bytestrings. This basically means you don't need the ord in the print calls, nor in the first parts of recv.

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 中的几行代码(你不需要 l0l1).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆