deriving from array.array

7 views
Skip to first unread message

Torsten Mohr

unread,
Jan 26, 2010, 12:41:44 PM1/26/10
to
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.

Alf P. Steinbach

unread,
Jan 26, 2010, 1:24:27 PM1/26/10
to
* 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

Alf P. Steinbach

unread,
Jan 26, 2010, 2:23:57 PM1/26/10
to
* Alf P. Steinbach:

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)

Torsten Mohr

unread,
Jan 26, 2010, 2:28:26 PM1/26/10
to
Hello,

thanks a lot for your hint, it works fine.

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

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

>> Though i explicitly
>> call __init__() for array.
>
> 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.


Alf P. Steinbach

unread,
Jan 26, 2010, 2:51:38 PM1/26/10
to
* Torsten Mohr:

>
> thanks a lot for your hint, it works fine.
>
>>> 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__.
>
> 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:

>>> import array
>>> id( array.array.__init__ )
10965560
>>> id( object.__init__ )
10965560
>>> array.array.__init__ is object.__init__
True
>>> _

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


>>> Though i explicitly
>>> call __init__() for array.
>> 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?

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

Reply all
Reply to author
Forward
0 new messages