Skip to content Skip to sidebar Skip to footer

Python 2 To Python 3

Having some trouble translating these two methods from python2 to python3. Python2: def send(self, data): if self.debug: print 'Send:', print ':'.join('%02x' %

Solution 1:

There are two main types of issues you need to address to make your code work in Python 3.

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.

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. 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.

  2. 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.

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:

defsend(self, data):
    if self.debug:
        print('Send:', end='')                     # new way to suppress the newlineprint(':'.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)

defrecv(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

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

Solution 2:

insteed of print a use print (a) like: python 2.x:

defsend(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)

defrecv(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.x:

defsend(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)

defrecv(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

Post a Comment for "Python 2 To Python 3"