A pseudo universal data encoder
def is_string(data):
    return isinstance(data, str)

def is_bytes(data):
    return isinstance(data, bytes)


I personally think that there isn't much gained by adding these two functions, but others may disagree (your post suggests you might). In otherwords, I would just write isinstance(data, str) wherever I see is_string. However, I think encodeable is sufficiently complicated to be a good stand-alone utility function.

I would also move:

s = str('spam')
r = r'eaggs'
b = b'slurm'
print('Before encoding')
print(s, r, b)
print(type(s), type(r), type(b), '\n')

print('After encoding')
s, r, b = encode(s), encode(r), encode(b)
print(encode(s), encode(r), encode(b))
print(type(s), type(r), type(b))


To a doctest.