inheritance, types, operator overload, head ache

thorley at gmail.com thorley at gmail.com
Fri Jul 7 17:39:00 EDT 2006


I'm working with the following code. I included some tests to make it
easy to see--if you run the code--what troubles I'm having.

Can some one *please* splain me why str(obj) works but not print obj,
and why obj.__int__() works, but not int(obj). I just don't get it. :(

BTW: The reason I'm going to all this mess is that I need a Byte object
that can
* print like a byte e.g. \x00
* adds like a string (concatinates)
* does bitwise math like a byte
* coereces to an int
* works with ''.join() -- The whole reason I'm inheriting from str
* Oh yeah, and some other classes inherit from it and have sequence
like behavior

Much thanks to any that can unveil the mystery and correct my broken
understanding.

regards
--
mthorley


<code>
import struct
class Byte(str): # Implement Bytes as str for easy adding and joining
    """Byte data type

        Inherits from str so join will work, but supports bitwise
operations
        via operator overloading. Given a digit it uses struct to
produce
        the correct string format. Given a non digit string, it
attempts to
        convert it to a digit using struct.unpack, and initialize its
self

        >>> b = Byte(1)
        >>> b
        '\\x01'
        >>> str(b)
        '\\x01'
        >>> b + b
        '\\x01\\x01'
        >>> ''.join([b,b])
        '\\x01\\x01'
        >>> b[0]
        '\\x01'
        >>> for i in b: i
        '\\x01'
        >>> b >> 8
        0
        >>> b << 8
        256
        >>> b._int
        1
        >>> len(b)
        1
        >>> type(b._int)
        <type 'int'>
        >>> b.__int__()
        1
        >>> int(b)
        1
        >>> print b
        1
    """
    def __new__(self, val):
        if type(val) == str and not val.isdigit():
            val = struct.unpack('B', val) #ensure input is valid struct
byte
        self._byte = struct.pack('B', val)
        self._int = int(val)
        return str.__new__(self, self._byte)

    def __int__(self):
        return self._int

    def __lshift__(self, x):
        return self._int << x

    def __rshift__(self, x):
        return self._int >> x

    def __len__(self):
        return 1


def _test():
    import doctest
    doctest.testmod()
    
if __name__ == '__main__':
    _test()
</code>




More information about the Python-list mailing list