title: Most Pythonic way to provide global configuration variables in config.py?
body: <p>In my endless quest in over-complicating simple stuff, I am researching the most 'Pythonic' way to provide global configuration variables inside the typical '<strong>config.py</strong>' found in Python egg packages. </p>
  
  <p>The traditional way (aah, good ol' <em>#define</em>!) is as follows:</p>
  
  <pre><code>MYSQL_PORT = 3306
  MYSQL_DATABASE = 'mydb'
  MYSQL_DATABASE_TABLES = ['tb_users', 'tb_groups']
  </code></pre>
  
  <p>Therefore global variables are imported in one of the following ways:</p>
  
  <pre><code>from config import *
  dbname = MYSQL_DATABASE
  for table in MYSQL_DATABASE_TABLES:
      print table
  </code></pre>
  
  <p>or:</p>
  
  <pre><code>import config
  dbname = config.MYSQL_DATABASE
  assert(isinstance(config.MYSQL_PORT, int))
  </code></pre>
  
  <p>It makes sense, but sometimes can be a little messy, especially when you're trying to remember the names of certain variables. Besides, providing a <strong>'configuration' object</strong>, with <strong>variables as attributes</strong>, might be more flexible. So, taking a lead from <strong>bpython</strong> config.py file, I came up with:</p>
  
  <pre><code>class Struct(object):
  
      def __init__(self, *args):
          self.__header__ = str(args[0]) if args else None
  
      def __repr__(self):
          if self.__header__ is None:
               return super(Struct, self).__repr__()
          return self.__header__
  
      def next(self):
          """ Fake iteration functionality.
          """
          raise StopIteration
  
      def __iter__(self):
          """ Fake iteration functionality.
          We skip magic attribues and Structs, and return the rest.
          """
          ks = self.__dict__.keys()
          for k in ks:
              if not k.startswith('__') and not isinstance(k, Struct):
                  yield getattr(self, k)
  
      def __len__(self):
          """ Don't count magic attributes or Structs.
          """
          ks = self.__dict__.keys()
          return len([k for k in ks if not k.startswith('__')\
                      and not isinstance(k, Struct)])
  </code></pre>
  
  <p>and a 'config.py' that imports the class and reads as follows:</p>
  
  <pre><code>from _config import Struct as Section
  
  mysql = Section("MySQL specific configuration")
  mysql.user = 'root'
  mysql.pass = 'secret'
  mysql.host = 'localhost'
  mysql.port = 3306
  mysql.database = 'mydb'
  
  mysql.tables = Section("Tables for 'mydb'")
  mysql.tables.users = 'tb_users'
  mysql.tables.groups =  'tb_groups'
  </code></pre>
  
  <p>and is used in this way:</p>
  
  <pre><code>from sqlalchemy import MetaData, Table
  import config as CONFIG
  
  assert(isinstance(CONFIG.mysql.port, int))
  
  mdata = MetaData(
      "mysql://%s:%s@%s:%d/%s" % (
           CONFIG.mysql.user,
           CONFIG.mysql.pass,
           CONFIG.mysql.host,
           CONFIG.mysql.port,
           CONFIG.mysql.database,
       )
  )
  
  tables = []
  for name in CONFIG.mysql.tables:
      tables.append(Table(name, mdata, autoload=True))
  </code></pre>
  
  <p>Which seems a more readable, expressive and flexible way of storing and fetching global variables inside a package.</p>
  
  <p>Lamest idea ever? What is the best practice for coping with these situations? What is <em>your</em> way of storing and fetching global names and variables inside your package?</p>