code: def under_name_scope(name_scope=None):
      
  
      def _impl(func):
          @functools.wraps(func)
          def wrapper(*args, **kwargs):
              scopename = kwargs.pop('name_scope', name_scope)
              if scopename is None:
                  scopename = func.__name__
  
              with tf.name_scope(scopename):
                  return func(*args, **kwargs)
          return wrapper
      return _impl
docs: Args:
          name_scope(str): the default scope to use. If None, will use the name of the function.
  
      Returns:
          A decorator which makes the function run under a name scope.
          The name scope is obtained by the following:
          1. The 'name_scope' keyword argument when the decorated function is called.
          2. The 'name_scope' argument of the decorator.
          3. (default) The name of the decorated function itself.
  
      Example:
  
      .. code-block:: python
  
          @under_name_scope()
          def rms(x):
              return tf.sqrt(
                  tf.reduce_mean(tf.square(x)))
  
          rms(tensor)  # will be called under name scope 'rms'
          rms(tensor, name_scope='scope')  # will be called under name scope 'scope'
  
  
      Todo:
          Add a reuse option.