<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def attrgetter(attr, key=None):
 """ Looks up ``attr`` on the target value. If the result is a callable, it will be called in place without arguments. If a ``key`` is given, it may be a function which maps the target value to something else before the attribute lookup takes place. Examples:: # Explicitly selecting the sources and then using a processor to allow the model # method to organize the data itself, you can still provide all the necessary # ORM hints to the column. # This is definitely superior to having sources=['get_address']. address = columns.TextColumn("Address", sources=['street', 'city', 'state', 'zip'], processor=attrgetter('get_address')) """

    def helper(instance, *args, **kwargs):
        value = instance
        for bit in attr.split('.'):
            value = getattr(value, bit)
            if callable(value):
                value = value()
        return value

    if key:
        helper = keyed_helper(helper)(key=key)
    return helper