title: Correct/Pythonic way to handle object with large number of attributes given as parameters
body: <p>I have a situation where an object has 15+ parameters where some are mandatory/optional/have defaults/don't have defaults. Let's say the class is <code>Foo</code> and the params are <code>Bar1</code>, <code>Bar2</code>, ..., <code>BarN</code>.</p>
  
  <p>I could program the class like:</p>
  
  <ol>
  <li><p>the traditional, tedious way. Easy to define defaults and verbose. However, code will be long and have lots of repetition.</p>
  
  <pre><code>class Foo(object):
      def __init__(self, bar1, bar2,...barN='somedefault' ):
          self.bar1 = bar1
          self.bar2 = bar2
          ...
          self.barN = barN
  </code></pre></li>
  <li><p>abusing(?) the <code>kwargs</code>. Does not support defaults.</p>
  
  <pre><code>class Foo(object):
  
      fields = [ 'bar1', 'bar2', ...n 'barN']
  
      def __init__(self, **kwargs ):
          for key in kwargs:
              if key in self.fields:
                  setattr(self, key, kwargs[key])
              else:
                  raise Exception('invalid attribute: {0}'.format(key))
  </code></pre></li>
  </ol>
  
  <p>For number 2, I could probably change the <code>fields</code> class attribute into a map <code>{ 'attribute_name': 'default_value' }</code> and then assign the <code>default_value</code> if that key was not in <code>kwargs</code>. </p>
  
  <p>The context where I'm working is that I'm creating objects that correspond to servers, firewall rules, storage disks, etc., that have a lot of attributes. In a lot of cases I get the attributes from the API so I can do number 2 (even without the validation). However, sometimes a user will create a firewall rule, attach it to a server and send it to an API (POST with JSON body).</p>
  
  <p>Is there some standard/pythonic way to handle objects with a large amount of attributes? Does the approach in #2 seem good or should I really go with the verbose #1 way?</p>
  
  <p>EDIT: one concrete example is a firewall rule object that has the following parameters:</p>
  
  <pre><code>    action
      destination_address_end
      destination_address_start
      destination_port_end
      destination_port_start
      direction
      family
      icmp_type
      position
      protocol
      source_address_end
      source_address_start
      source_port_end
      source_port_start
  </code></pre>
  
  <p>Right now I'm leaning towards something like:</p>
  
  <pre><code>class FirewallRule(object):
  
      attributes = {
          'action': 'default_value',
          'destination_address_end': 'default_value',
          'destination_address_start': 'default_value',        
          'destination_port_end': 'default_value',
          'destination_port_start': 'default_value',
          'direction': 'default_value',
          'family': 'default_value',
          'icmp_type': 'default_value',
          'position': 'default_value',
          'protocol': 'default_value',
          'source_address_end': 'default_value',
          'source_address_start': 'default_value',
          'source_port_end': 'default_value',
          'source_port_start': 'default_value'
      }
  
      def __init__(self, **kwargs ):
          for key in kwargs:
              valur_or_default = kwargs.get(key, attributes[key])
              setattr(self, key, valur_or_default)
  </code></pre>
  
  <p>(In production code I'd obviously add better error handling and validation)</p>