Get attribute value from object.

    :param obj: object
    :param name: attribute or key name
    :param default: when attribute or key missing, return default; if obj is a
        dict and use getitem, default will not be used.
    :param getitem: when object is a dict, use getitem or get
    :return: attribute or key value, or raise KeyError/AttributeError

def xgetattr(obj: object, name: str, default=_sentinel, getitem=False):
    """Get attribute value from object.

    :param obj: object
    :param name: attribute or key name
    :param default: when attribute or key missing, return default; if obj is a
        dict and use getitem, default will not be used.
    :param getitem: when object is a dict, use getitem or get
    :return: attribute or key value, or raise KeyError/AttributeError
    """

    if isinstance(obj, dict):
        if getitem:
            # In tune with `dict.__getitem__` method.
            return obj[name]
        else:
            # In tune with `dict.get` method.
            val = obj.get(name, default)
            return None if val is _sentinel else val
    else:
        # If object is not a dict, in tune with `getattr` method.
        val = getattr(obj, name, default)
        if val is _sentinel:
            msg = '%r object has no attribute %r' % (obj.__class__, name)
            raise AttributeError(msg)
        else:
            return val