text: #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  
  __author__ = 'Daniel Zhang (張道博)'
  __copyright__ = 'Copyright (c) 2014, University of Hawaii Smart Energy Project'
  __license__ = 'https://raw.github' \
                '.com/Hawaii-Smart-Energy-Project/Maui-Smart-Grid/master/BSD' \
                '-LICENSE.txt'
  
  import inspect
  
  
  class MSGPythonUtil(object):
      """
      Utility methods related to the Python language.
  
      Usage:
  
      from msg_python_util import MSGPythonUtil
      pythonUtil = MSGPythonUtil()
  
      """
  
      def __init__(self):
          """
          Constructor.
          """
          pass
  
  
      def callerName(self, skip = 2):
          """
          Get a name of a caller in the format module.class.method
  
             `skip` specifies how many levels of stack to skip while getting
             caller
             name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.
  
             An empty string is returned if skipped levels exceed stack height
  
          Source: http://code.activestate.com/recipes/578352-get-full-caller
          -name-packagemodulefunction/
          """
          stack = inspect.stack()
          start = 0 + skip
          if len(stack) < start + 1:
              return ''
          parentframe = stack[start][0]
  
          name = []
          module = inspect.getmodule(parentframe)
          # `modname` can be None when frame is executed directly in console
          # TODO(techtonik): consider using __main__
          if module:
              name.append(module.__name__)
          # detect classname
          if 'self' in parentframe.f_locals:
              # I don't know any way to detect call from the object method
              # XXX: there seems to be no way to detect static method call - it
              # will
  
              # be just a function call
              name.append(parentframe.f_locals['self'].__class__.__name__)
          codename = parentframe.f_code.co_name
          if codename != '<module>':  # top level usually
              name.append(codename)  # function or a method
          del parentframe
          return ".".join(name)
  