Python class __init__(mandatory arguments?)
Bengt Richter
bokr at oz.net
Sun Jun 15 19:45:16 EDT 2003
On 15 Jun 2003 23:02:26 GMT, Lee John Moore <leej at dsl.pipex.com> wrote:
>Just for confirmation really: When I create a custom class, is
>it *really* true that def __init__() arguments can only ever be
>optional? Eg:
>
>class MyClass:
> param1 = None
> param2 = None
> def __init__(self, param1, param2):
> param1 = self.param1
> param2 = self.param2
You have the 'self.' on the wrong side of the '=' if you
want to bind the parameters as instance attributes.
If you wanted to rebind the class attributes, you didn't. Instead
you bound two locals of the __init__ method to the class attributes,
which would be found because they would not already exist as instance attributes.
And, barring further code in __init__, nothing would be done with the local bindings,
which would disappear on exit from __ini__.
>
>myinstance1 = MyClass()
>myinstance2 = MyClass("Hello", "World")
>[snip]
>
>I'm really unhappy that myinstance1 is allowed. ;-)
I don't think you actually tried it in the form above ;-)
The parameters without default arguments should result in an exception if not provided.
Your code above is legal, though I doubt if it does what you intended, but it does
result in a complaint about missing arguments (the one given is the instance itself,
bound to self).
>>> class MyClass:
... param1 = None
... param2 = None
... def __init__(self, param1, param2):
... param1 = self.param1
... param2 = self.param2
...
>>> myinstance1 = MyClass()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __init__() takes exactly 3 arguments (1 given)
Did you get something different?
>>> myinstance2 = MyClass("Hello", "World")
It liked that, as far as arguments go.
>>> myinstance1
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'myinstance1' is not defined
myinstance1 was not bound because of the exception calling __init__
>>> myinstance2
< __main__.MyClass instance at 0x00796A80>
Was bound ok, but no instance attributes resulted.
>>> vars(myinstance2)
{}
However, the class attributes are findable:
>>> dir(myinstance2)
['__doc__', '__init__', '__module__', 'param1', 'param2']
>>> myinstance2.param1
(Interactive evaluation resulting in None doesn't print anything).
>>> repr(myinstance2.param1)
'None'
But repr() of same does.
>>> vars(myinstance2.__class__)
{'__init__': <function __init__ at 0x007A63C0>, '__module__': '__main__', 'param2': None, 'param
1': None, '__doc__': None}
The contents of the class dict show the param1 and param2 values you bound in the class, as
well as your __init__ and a couple of automatically produced names.
>
>I'm so accustomed to constructor arguments being mandatory in
>C++ & OP classes....and yes, yes, I realise __init__() is not a
>constructor (even though it looks like one), but if there's a
>way I can *force* arguments upon class instantiation, I'd like
>to know about it. :-)
How much more force do you need? (You can check types and raise
whatever exception you want also, if you have to).
Regards,
Bengt Richter
More information about the Python-list
mailing list