docs: 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