constructor of subclass and base's tp_new()
Greg Ewing (using news.cis.dfn.de)
me at privacy.net
Thu Mar 27 00:00:59 EST 2003
Maciej Kalisiak wrote:
> static PyObject*
> noddy_new_noddy(PyObject* self, PyObject* args)
> {
> noddy_NoddyObject* noddy;
>
> if (!PyArg_ParseTuple(args,":new_noddy"))
> return NULL;
>
> noddy = PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
>
> return (PyObject*)noddy;
> }
>
> What is the role of `self' in *this* factory function??
Nothing. It's there simply because it's part of the
signature of every C-implemented method or function.
In this case, it's unused (it's a function, not a
method, so it gets called with self == NULL).
> ,----
> | from State import State
> | class StateOfSize5(State):
> | def __init__(self):
> | State.__init__(self, 5)
> |
> | s = State(5) # this runs OK
> | s = StateOfSize5() # ERROR
> | s = StateOfSize5(5) # a workaround, but undermines the purpose of subclass
> `----
>
> The error I get is:
> TypeError: state_new() takes exactly 1 argument (0 given)
That's because everything you pass to the constructor gets
passed to __new__ as well as __init__.
One way to deal with this is to make your tp_new
accept any number of arguments, and ignore the ones it's
not interested in. That's what object.__new__ seems to
do, for instance.
Otherwise, whenever a subclass overrides __init__ to have
a different number of arguments, it will have to override
__new__ correspondingly.
You have to do this with some of the builtin types, e.g.
>>> class S(str):
... def __init__(cls, x, y):
... print x, y
...
>>> s = S(55, 66)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: str() takes at most 1 argument (2 given)
>>> class S(str):
... def __init__(cls, x, y):
... print x, y
... def __new__(cls, x, y):
... return str.__new__(cls, x)
...
>>> s = S(55, 66)
55 66
>>> s
'55'
--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg
More information about the Python-list
mailing list