title: Multiple constructors: the Pythonic way?
body: <p>I have a container class that holds data. When the container is created, there are different methods to pass data.</p>
  
  <ol>
  <li>Pass a file which contains the data</li>
  <li>Pass the data directly via arguments</li>
  <li>Don't pass data; just create an empty container</li>
  </ol>
  
  <p>In Java, I would create three constructors. Here's how it would look like if it were possible in Python:</p>
  
  <pre><code>class Container:
  
      def __init__(self):
          self.timestamp = 0
          self.data = []
          self.metadata = {}
  
      def __init__(self, file):
          f = file.open()
          self.timestamp = f.get_timestamp()
          self.data = f.get_data()
          self.metadata = f.get_metadata()
  
      def __init__(self, timestamp, data, metadata):
          self.timestamp = timestamp
          self.data = data
          self.metadata = metadata
  </code></pre>
  
  <p>In Python, I see three obvious solutions, but none of them is pretty:</p>
  
  <p><strong>A</strong>: Using keyword arguments:</p>
  
  <pre><code>def __init__(self, **kwargs):
      if 'file' in kwargs:
          ...
      elif 'timestamp' in kwargs and 'data' in kwargs and 'metadata' in kwargs:
          ...
      else:
          ... create empty container
  </code></pre>
  
  <p><strong>B</strong>: Using default arguments:</p>
  
  <pre><code>def __init__(self, file=None, timestamp=None, data=None, metadata=None):
      if file:
          ...
      elif timestamp and data and metadata:
          ...
      else:
          ... create empty container
  </code></pre>
  
  <p><strong>C</strong>: Only provide constructor to create empty containers. Provide methods to fill containers with data from different sources.</p>
  
  <pre><code>def __init__(self):
      self.timestamp = 0
      self.data = []
      self.metadata = {}
  
  def add_data_from_file(file):
      ...
  
  def add_data(timestamp, data, metadata):
      ...
  </code></pre>
  
  <p>Solutions A and B are basically the same. I don't like doing the if/else, especially since I have to check if all arguments required for this method were provided. A is a bit more flexible than B if the code is ever to be extended by a fourth method to add data.</p>
  
  <p>Solution C seems to be the nicest, but the user has to know which method he requires. For example: he cant do <code>c = Container(args)</code> if he doesn't know what <code>args</code> is.</p>
  
  <p>Whats the most Pythonic solution?</p>