Inheriting from int or long

S

snorble

I started creating a simple "bits" class, intended to act like a array
of bits. This was my initial idea, basically just overriding the
string representation to display the bitmask (so far):

class bits(long):
def __str__ (self):
s = ''
if self == 0L:
s += '-'
else:
x = self
while x >= 1:
if x & 1L: s = '#' + s
else: s = '-' + s
x >>= 1
return s

My thought was this will act like a Long, and so should act like an
array of bits with arbitrary precision, supporting the standard
bitwise operations, along with others I may add.
72

So obviously when I attempt a bitwise operation (ex. b <<= 1), b is
being assigned the result of b << 1, which is a Long.
<type 'long'>

Is there any way around this without reimplementing all of the bitwise
operators? It's not the biggest deal to reimplement the operators, but
it kind of defeats the benefit of inheriting from an integer type.

If there isn't a way around this, then I am curious in what situations
it would be beneficial to inherit from an int or long. This issue
seems more related to numeric types, since they are so centered around
operations that involve assignment, as opposed to, say, a List, which
has some operators (ex. +=), but does not depend on them (ex. use
append() instead).
 
D

Diez B. Roggisch

I started creating a simple "bits" class, intended to act like a array
of bits. This was my initial idea, basically just overriding the
string representation to display the bitmask (so far):

class bits(long):
def __str__ (self):
s = ''
if self == 0L:
s += '-'
else:
x = self
while x >= 1:
if x & 1L: s = '#' + s
else: s = '-' + s
x >>= 1
return s

My thought was this will act like a Long, and so should act like an
array of bits with arbitrary precision, supporting the standard
bitwise operations, along with others I may add.

72

So obviously when I attempt a bitwise operation (ex. b <<= 1), b is
being assigned the result of b << 1, which is a Long.

<type 'long'>

Is there any way around this without reimplementing all of the bitwise
operators? It's not the biggest deal to reimplement the operators, but
it kind of defeats the benefit of inheriting from an integer type.

No, there isn't. How is the existing operation of the operator going to know
that you want an instance of bits instead of long? It can't possibly know
that, even if it looked at the class of one or even both of it's operands:
it could be that instantiating a bits-object needed a reference to
TheCommonApplicationContextThingy or so....
If there isn't a way around this, then I am curious in what situations
it would be beneficial to inherit from an int or long. This issue
seems more related to numeric types, since they are so centered around
operations that involve assignment, as opposed to, say, a List, which
has some operators (ex. +=), but does not depend on them (ex. use
append() instead).

It's beneficial if you want special behavior - but I don't see how the
requirement of overloading the methods to make thinks work affect the grade
of "beneficiality".

Diez
 
T

Terry Reedy

|I started creating a simple "bits" class, intended to act like a array
| of bits. This was my initial idea, basically just overriding the
| string representation to display the bitmask (so far):

For this purpose, for the reason you discovered, simply writing a bit_rep
function would likely be better ;-)

[discovery of need to override possibly all of long's special methods]

|| Is there any way around this without reimplementing all of the bitwise
| operators? It's not the biggest deal to reimplement the operators, but
| it kind of defeats the benefit of inheriting from an integer type.

Since the code needed is mostly boilerplate, I think the standard Python
distribution could and should contain builtin type subclass template files,
at least for int/long/float for the reasons you give below.

| If there isn't a way around this, then I am curious in what situations
| it would be beneficial to inherit from an int or long.

As I already said, if you only want to change __str__, consider a
standalone function. If you want to change the behavior of any of the
operations and still tie into the syntax, then the alternative, wrapping
the builtin, may be worse.

class mysub(int):
...
def __add__(self, other): return mysub(self,other)

versus

class mywrap():
def __init__(self,dat):
self._int = dat # should test type
def __add__(self, other): return mywrap(self._int + other._int)

| This issue
| seems more related to numeric types, since they are so centered around
| operations that involve assignment, as opposed to, say, a List, which
| has some operators (ex. +=), but does not depend on them (ex. use
| append() instead).

Terry Jan Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top