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