title: Differing from lists/tuples from strings during iteration
body: <p>Is a common pattern to write functions that accept an argument, and if the argument is a scalar like a number or a string, you apply some operation on it, and if the argument is a iterable, you apply the same operation on each element of this iterable</p>
  
  <p>The problem is that string is iterable, so I can't rely on <em>Ask for forgiveness not for permission</em> for achieving this, because <code>iter('hello world')</code> will not raise TypeError.</p>
  
  <p>For example</p>
  
  <pre class="lang-py prettyprint-override"><code>def apply_(func, val):
      try:
          for v in iter(val):
              print(func(v), end=' ')
          print()
      except TypeError:
          print(func(val))
  
  
  apply_(lambda x: x+1, 1) # 2 ...  Ok
  apply_(lambda x: x*2, range(3)) # 0 2 4 ... Ok
  apply_(str.upper, ['hello', 'world']) # HELLO WORLD ... Okay
  apply_(str.upper, 'hello world') # H E L L O   W O R L D, ... oops
  </code></pre>
  
  <p>I can <em>ask for persmission</em>. But this will work only for subtypes of string.</p>
  
  <pre class="lang-py prettyprint-override"><code>def apply_safe(func, val):
      if issubclass(type(val), str):
          print(func(val))
          return
  
      try:
          for v in iter(val):
              print(func(v), end=' ')
          print()
      except TypeError:
          print(func(val))
  </code></pre>
  
  <p>Another option is to add this logic to the type, which seems to be the right way of doing this since being iterable is undesired (for this case) behavior of string. But this is error prone for the caller, soon or later it will forget to call it with <code>NonIterableString</code> or any other class.</p>
  
  <pre class="lang-py prettyprint-override"><code>class NonIterableString(str):
      def __iter__(self):
          raise TypeError()
  
  apply(str.upper, NonIterableString('hello world')) # HELLO WORLD
  </code></pre>
  
  <p>The last solution I found is this which fix my problem but may not work for existing code is this</p>
  
  <pre class="lang-py prettyprint-override"><code>def apply_multi(func, *vals):
      for v in vals:
          print(func(v), end=' ')
      print()
  </code></pre>
  
  <p>This seems to be the more idiomatic one. It always works, is small and elegant, but because it doesn't face the problem, it smartly circumvent it. Here the problem is that I need to write a function like this for each case of this, which it doesn't seems to be a bad idea, but is still verbose...</p>
  
  <p>Finally here is the complete example</p>
  
  <pre class="lang-py prettyprint-override"><code>def apply_(func, val):
      try:
          for v in iter(val):
              print(func(v), end=' ')
          print()
      except TypeError:
          print(func(val))
  
  def apply_safe(func, val):
      if (issubclass(type(val), str)):
          print(func(val))
          return
  
      try:
          for v in iter(val):
              print(func(v), end=' ')
          print()
      except TypeError:
          print(func(val))
  
  def apply_multi(func, *vals):
      for v in vals:
          print(func(v), end=' ')
      print()
  
  class NonIterableString(str):
      def __iter__(self):
          raise TypeError()
  
  apply_(lambda x: x+1, 1) # 2 =&gt; ok
  apply_(lambda x: x*2, range(3)) # 0 2 4 =&gt; ok
  apply_(str.upper, ['hello', 'world']) # HELLO WORLD =&gt; ok
  apply_(str.upper, 'hello world') # H E L L O   W O R L D =&gt; oops
  apply_(str.upper, NonIterableString('hello world')) # HELLO WORLD =&gt; ok
  apply_safe(str.upper, 'Hello world') # HELLO WORLD =&gt;j
  apply_multi(str.upper, 'hello world') # HELLO WORLD =&gt; ok
  </code></pre>
  
  <p>Finally my question is, is there any <em>AFFNFP</em> way of dealing strings in python like a scalar type instead of an iterable one?</p>