What's a good reason to allow defining instance variable in such a way?
I think it's important to note that self
inside your __init__
function is exactly the same as self
in any other method on that instance. It's also the same as a
outside the class. The magic of the __init__
method lies in when it gets called and nothing else (which is true of all python magic methods). To have __init__
"freeze" the object in one way or another would go against the way things have always been done in python.
So, I would say that the "good reason" is because it makes things very consistent.
And, is it dangerous?
Yes. It can be.
The practice of intentionally adding methods/attributes to an instance is known as Monkey Patching (also occasionally called Duck Punching)1 -- And it really shouldn't be done unless you don't have any other options.
The practice of unintentionally adding methods/attributes to an instance is known as creating bugs (and we've all done it :-).
Fortunately, there are tools to help you prevent these types of bugs. Linters are the most common. I personally use pylint
to help warn me about these sorts of bugs.
Between the linter and using common sense (see above about not Monkey Patching), I've very rarely been hit with a hard-to-track bug because of this part of python's ideology.
1I suppose that it isn't duck punching if you add more attributes in a later instance method -- But you probably shouldn't be doing that either . . .