The key to this is helping with unit testing. If I have a busy __init__ (i.e. __init__ that does complex initialization), I can't just instantiate the class object, but I need to mock all the methods called in the dependencies inside __init__ . p>
To illustrate this problem, here is an example:
class SomeClass(object): def __init__(self, dep1, dep2, some_string): self._dep1 = dep1 self._dep2 = dep2 self._some_string = some_string
To test the fun* functions, each test must perform a complex construct.
class TestSomeClass(TestCase): def create_SomeClass(self, some_string): dep1 = Mock()
I find this redundant and would like to know how these problems can be elegantly handled in python, if not by moving work from the constructor.
DECISION:
As @ecatmur suggested, in order to test a specific function, this code should do the trick:
def test_some_method(): mobject = Mock(SomeClass) SomeClass.fun1(mobject)
With this approach, all methods will be mocked. If fun1 calls another method that you want to execute (e.g. fun2 ), you can do it like this:
def test_some_method(): mobject = Mock(SomeClass) mobject.fun2 = SomeClass.fun2.__get__(mobject) SomeClass.fun1(mobject)
SomeClass.fun2.__get__(mobject) will create an instancemethod that will ensure the correct binding.
ยกViva el Python!
ORIGINAL QUESTION:
The original question centered around moving the work done in __init__ to a separate init method and various issues that rotate this approach. My usual approach is to do this
class SomeClass(object): def __init__(self, dep1, dep2, some_string) self._dep1 = dep1 self._dep2 = dep2 # lots of mumbo-jumbo here...
do it
class SomeClass(object): def __init__(self, dep1, dep2) self._dep1 = dep1 self._dep2 = dep2 def initiate(self, some-string) # lots of mumto-jumbo here...
The general consensus was that moving work from __init__ not common practice and would be pointless for experienced python developers.