deriving from array.array

T

Torsten Mohr

Hello,

i try to derive a class from array.array:


import array

class Abc(array.array):
def __init__(self, a, b):
array.array.__init__(self, 'B')
self.a = a
self.b = b


a = Abc(4, 5)
print a
print a.a


I get an error for "a = Abc(4, 5)", seems the parameters are
forwarded to array's __init__ as they are. Though i explicitly
call __init__() for array.

I'd like to use array and make sure it's type is always 'B'.
I'd like to derive because i don't want to rewrite all the methods like
__getiem__ for my class and then call array's __getitem__.

How do i best derive from array.array?


Thanks for any hints,
Torsten.
 
A

Alf P. Steinbach

* Torsten Mohr:
Hello,

i try to derive a class from array.array:


import array

class Abc(array.array):
def __init__(self, a, b):
array.array.__init__(self, 'B')
self.a = a
self.b = b


a = Abc(4, 5)
print a
print a.a


I get an error for "a = Abc(4, 5)", seems the parameters are
forwarded to array's __init__ as they are.

No, with CPython they're forwarded to __new__.

Though i explicitly
call __init__() for array.

That's the constructor inherited from 'object', it takes no args (except the
self arg).

I'd like to use array and make sure it's type is always 'B'.
I'd like to derive because i don't want to rewrite all the methods like
__getiem__ for my class and then call array's __getitem__.

How do i best derive from array.array?

<code>
import array

class ByteArray( array.array ):
def __new__( self, *args ):
return array.array.__new__( self, "B" )

def __init__( self, a, b ):
array.array.__init__( self )
self.a = a
self.b = b

a = ByteArray( 4, 5 )
print( a )
print( a.a )
</code>


Disclaimer: I'm not a Python programmer. :)


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* Torsten Mohr:

No, with CPython they're forwarded to __new__.



That's the constructor inherited from 'object', it takes no args (except
the self arg).



<code>
import array

class ByteArray( array.array ):
def __new__( self, *args ):
return array.array.__new__( self, "B" )

def __init__( self, a, b ):
array.array.__init__( self )
self.a = a
self.b = b

a = ByteArray( 4, 5 )
print( a )
print( a.a )
</code>


Disclaimer: I'm not a Python programmer. :)

Hm, good that I included a disclaimer. The above code is technically OK but it
is misleading. The first argument to '__new__' is not a self argument but a type
argument, better called 'cls' or some such.

From the docs, "__new__() is a static method (special-cased so you need not
declare it as such) that takes the class of which an instance was requested as
its first argument"


Cheers,

- Alf (self-correcting)
 
T

Torsten Mohr

Hello,

thanks a lot for your hint, it works fine.
No, with CPython they're forwarded to __new__.

Not sure if i understand this correctly, if i derive from other
classes (like wxpython widgets) i always call the bases __init__ .
That's the constructor inherited from 'object', it takes no args (except
the self arg).

Is there a way to find out what i need to call? I haven't found much in
the documentation. From writing C extensions i knew about the "new" entry
in the PyTypeObject struct but it seems there's more behind it.
In docs.python.org i did not find much, is there an URL where i can read
more?


Best regards,
Torsten.
 
A

Alf P. Steinbach

* Torsten Mohr:
thanks a lot for your hint, it works fine.


Not sure if i understand this correctly, if i derive from other
classes (like wxpython widgets) i always call the bases __init__ .

Well, creation of an object happens in two phases: allocation and initialization.

Allocation reserves memory for the object and creates a sort of default object
in that memory. This is the job of __new__. The object doesn't exist at all
before __new__ is called.

Initialization then outfits the object with all that's required for a proper
object of class T. This is the job of __init__. __init__ as passed as argument
the default object created by __new__.

CPython's array.array does both in __new__. It does not override the __init__ it
inherits from 'object'. To wit:

So overriding __init__ doesn't override any of array.array's functionality.

But you'd have to override __new__ anyway, because with array.array the first
argument has to be a type code specifying the element type of the array object
the __new__ should create. An alternative design instead of those type codes
could have had one subclass for each element type, essentially what you're
doing, except you're only doing one of those subclasses. Then there would be no
issue with __new__.

Is there a way to find out what i need to call?

Testing. :)

I haven't found much in
the documentation. From writing C extensions i knew about the "new" entry
in the PyTypeObject struct but it seems there's more behind it.
In docs.python.org i did not find much, is there an URL where i can read
more?

Don't know, sorry. Google?


Cheers,

- Alf
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,156
Latest member
KetoBurnSupplement
Top