def patch_object(obj, attr_name, patched_value):
    """Patches an object and returns an instance of :class:`fudge.patcher.PatchHandler` for later restoration.

    Note that if *obj* is not an object but a path to a module then it will be imported.

    You may want to use a more convenient wrapper :func:`with_patched_object` or :func:`patched_context`

    Example::

        >>> from fudge import patch_object
        >>> class Session:
        ...     state = 'clean'
        ...
        >>> patched_session = patch_object(Session, "state", "dirty")
        >>> Session.state
        'dirty'
        >>> patched_session.restore()
        >>> Session.state
        'clean'

    Here is another example showing how to patch multiple objects at once::

        >>> class Session:
        ...     state = 'clean'
        ...
        >>> class config:
        ...     session_strategy = 'database'
        ...
        >>> patches = [
        ...     patch_object(config, "session_strategy", "filesystem"),
        ...     patch_object(Session, "state", "dirty")
        ... ]
        >>> try:
        ...     # your app under test would run here ...
        ...     print "(while patched)"
        ...     print "config.session_strategy=%r" % config.session_strategy
        ...     print "Session.state=%r" % Session.state
        ... finally:
        ...     for p in patches:
        ...         p.restore()
        ...     print "(patches restored)"
        (while patched)
        config.session_strategy='filesystem'
        Session.state='dirty'
        (patches restored)
        >>> config.session_strategy
        'database'
        >>> Session.state
        'clean'

    """
    if isinstance(obj, (str, unicode)):
        obj_path = adjusted_path = obj
        done = False
        exc = None
        at_top_level = False
        while not done:
            try:
                obj = __import__(adjusted_path)
                done = True
            except ImportError:
                # Handle paths that traveerse object attributes.
                # Such as: smtplib.SMTP.connect
                #          smtplib <- module to import
                adjusted_path = adjusted_path.rsplit('.', 1)[0]
                if not exc:
                    exc = sys.exc_info()
                if at_top_level:
                    # We're at the top level module and it doesn't exist.
                    # Raise the first exception since it will make more sense:
                    etype, val, tb = exc
                    raise etype, val, tb
                if not adjusted_path.count('.'):
                    at_top_level = True
        for part in obj_path.split('.')[1:]:
            obj = getattr(obj, part)

    handle = PatchHandler(obj, attr_name)
    handle.patch(patched_value)
    return handle
Patches an object and returns an instance of :class:`fudge.patcher.PatchHandler` for later restoration.

    Note that if *obj* is not an object but a path to a module then it will be imported.

    You may want to use a more convenient wrapper :func:`with_patched_object` or :func:`patched_context`

    Example::

        >>> from fudge import patch_object
        >>> class Session:
        ...     state = 'clean'
        ...
        >>> patched_session = patch_object(Session, "state", "dirty")
        >>> Session.state
        'dirty'
        >>> patched_session.restore()
        >>> Session.state
        'clean'

    Here is another example showing how to patch multiple objects at once::

        >>> class Session:
        ...     state = 'clean'
        ...
        >>> class config:
        ...     session_strategy = 'database'
        ...
        >>> patches = [
        ...     patch_object(config, "session_strategy", "filesystem"),
        ...     patch_object(Session, "state", "dirty")
        ... ]
        >>> try:
        ...     # your app under test would run here ...
        ...     print "(while patched)"
        ...     print "config.session_strategy=%r" % config.session_strategy
        ...     print "Session.state=%r" % Session.state
        ... finally:
        ...     for p in patches:
        ...         p.restore()
        ...     print "(patches restored)"
        (while patched)
        config.session_strategy='filesystem'
        Session.state='dirty'
        (patches restored)
        >>> config.session_strategy
        'database'
        >>> Session.state
        'clean'