def with_switch(cls):
    """
    Class decorator that adds two attributes to the `cls` class:

    * `switch` -- a defaultdict (or collection of other type, created with
      cls.custom_switch_factory) mapping case keys to case objects (that
      have been decorated with the @case() decorator;

    * `get_default_case` -- a static method that returns the default case
      object, i.e. one which has been decorated with @case(default=True)
      (or returns None if no object has been decorated in that way).

    Typically, case object is a callable method (but doesn't need to be).
    """
    keys_to_cases = {}
    for name, obj in inspect.getmembers(cls):
        for key in getattr(obj, '_switch_case_keys', ()):
            _obj = keys_to_cases.setdefault(key, obj)
            if _obj is not obj:
                raise ValueError('More than one case for key %r' % key)
    default_case = keys_to_cases.pop(_DEF_CASE_KEY, None)
    get_default_case = (lambda: default_case)
    switch_factory = getattr(cls, 'custom_switch_factory', defaultdict)
    kwargs = getattr(cls, 'custom_switch_factory_kwargs', {})
    cls.switch = switch_factory(get_default_case, keys_to_cases, **kwargs)
    cls.get_default_case = staticmethod(get_default_case)
    return cls

    Class decorator that adds two attributes to the `cls` class:

    * `switch` -- a defaultdict (or collection of other type, created with
      cls.custom_switch_factory) mapping case keys to case objects (that
      have been decorated with the @case() decorator;

    * `get_default_case` -- a static method that returns the default case
      object, i.e. one which has been decorated with @case(default=True)
      (or returns None if no object has been decorated in that way).

    Typically, case object is a callable method (but doesn't need to be).
    
recipes/Python/577864_Fast_elegant_switchcaselike/recipe-577864.py