title: Dynamic Class Instantiation in Python
body: <p>I have a bunch of classes in a module. Let's say:</p>
  
  <pre><code>'''players.py'''
  
  class Player1:
      def __init__(self, name='Homer'):
          self.name = name
  
  class Player2:
      def __init__(self, name='Barney'):
          self.name = name
  
  class Player3:
      def __init__(self, name='Moe'):
          self.name = name
  ...
  </code></pre>
  
  <p><br/></p>
  
  <p>Now, in another module, I want to dynamically load all classes in <code>players.py</code> and instantiate them. I use the python <code>inspect</code> module for this.</p>
  
  <pre><code>'''main.py'''
  import inspect
  import players
  
  ai_players = inspect.getmembers(players, inspect.isclass)
  # ai_players is now a list like: [('Player1',&lt;class instance&gt;),(...]
  ai_players = [x[1] for x in ai_players]
  # ai_players is now a list like: [&lt;class instance&gt;, &lt;class...]
  
  # now let's try to create a list of initialized objects
  ai_players = [x() for x in ai_players]
  </code></pre>
  
  <p>I would <code>ai_players</code> expect to be a list of object instances like so (let's suppose <code>__str__</code> returns the name): <code>['Homer', 'Barney...]</code></p>
  
  <p>However, I get the following error</p>
  
  <pre><code>TypeError: __init__() takes exactly 2 arguments (1 given)
  </code></pre>
  
  <p><br/></p>
  
  <p>The funny thing is that when I don't instantiate the class objects in a list comprehension or a for loop everything works fine.</p>
  
  <pre><code># this does not throw an error
  ai_player1 = ai_players[0]()
  print ai_player1
  # &gt;&gt; 'Homer'
  </code></pre>
  
  <p><br/></p>
  
  <p>So why doesn't Python allow me to instantiate the classes in a list comprehensions/for loop (I tried it in a for loop, too)?</p>
  
  <p>Or better: How would you go about dynamically loading all classes in a module and instantiating them in a list?</p>
  
  <p>* Note, I'm using Python 2.6</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Turns out I oversimplified my problem and the above code is just fine.
  However if I change <code>players.py</code> to</p>
  
  <pre><code>'''players.py'''
  
  class Player():
      """This class is intended to be subclassed"""
      def __init__(self, name):
          self.name = name
  
  class Player1(Player):
      def __init__(self, name='Homer'):
          Player.__init__(self, name)
  
  class Player2(Player):
      def __init__(self, name='Barney'):
          Player.__init__(self, name)
  
  class Player3(Player):
      def __init__(self, name='Moe'):
          Player.__init__(self, name)
  </code></pre>
  
  <p>and change the 5th line in <code>main.py</code> to</p>
  
  <pre><code>ai_players = inspect.getmembers(players, 
               lambda x: inspect.isclass(x) and issubclass(x, players.Player))
  </code></pre>
  
  <p>I encounter the described problem. Also that doesn't work either (it worked when I tested it on the repl)</p>
  
  <pre><code>ai_player1 = ai_players[0]()
  </code></pre>
  
  <p>It seems to have something to do with inheritance and default arguments. If I change the base class <code>Player</code> to</p>
  
  <pre><code>class Player():
      """This class is intended to be subclassed"""
      def __init__(self, name='Maggie'):
          self.name = name
  </code></pre>
  
  <p>Then I don't get the error but the players' names are always 'Maggie'.</p>
  
  <p><strong>EDIT2:</strong></p>
  
  <p>I played around a bit and it turns out the getmembers function somehow "eats" the default parameters. Have a look at this log from the repl:</p>
  
  <pre><code>&gt;&gt;&gt; import players
  &gt;&gt;&gt; import inspect
  &gt;&gt;&gt; ai_players = inspect.getmembers(players, 
  ...              lambda x: inspect.isclass(x) and issubclass(x, players.Player))
  &gt;&gt;&gt; ai_players = [x[1] for x in ai_players]
  &gt;&gt;&gt; ai_players[0].__init__.func_defaults
  &gt;&gt;&gt; print ai_players[0].__init__.func_defaults
  None
  &gt;&gt;&gt; players.Player1.__init__.func_defaults
  ('Homer',)
  </code></pre>
  
  <p>Do you know of any alternative to getmembers from the inspect module?</p>
  
  <p><strong>EDIT3:</strong></p>
  
  <blockquote>
    <p>Note that issubclass() returns True if given the SAME class twice. (Tryptich)</p>
  </blockquote>
  
  <p>That's been the evildoer</p>