title: decorator function syntax python
body: <p>I am learning decorator functions in python and I am wrapping my head around the @ syntax. </p>
  
  <p>Here is a simple example of a decorator function which calls the relevant function twice.</p>
  
  <pre><code>def duplicator(func):
      @functools.wraps(func)
      def wrapper(*args, **kwargs):
          func(*args, **kwargs)
          func(*args, **kwargs)
      return wrapper
  </code></pre>
  
  <p>If I understand correctly, it appears that: </p>
  
  <pre><code>@duplicator
  def print_hi():
      print('We will do this twice')
  </code></pre>
  
  <p>Is equivalent to: </p>
  
  <pre><code>print_hi = duplicator(print_hi)
  print_hi()
  </code></pre>
  
  <p>However, let's consider if I move to a more complex example. E.g. instead of calling the function twice, I want to call it a user-defined amount of times. </p>
  
  <p>Using an example from here: <a href="https://realpython.com/primer-on-python-decorators/" rel="nofollow noreferrer">https://realpython.com/primer-on-python-decorators/</a> </p>
  
  <pre><code>def repeat(num_times):
      def decorator_repeat(func):
          @functools.wraps(func)
          def wrapper_repeat(*args, **kwargs):
              for _ in range(num_times):
                  value = func(*args, **kwargs)
              return value
          return wrapper_repeat
      return decorator_repeat
  </code></pre>
  
  <p>I can call this via: </p>
  
  <pre><code>@repeat(num_times=4)
  def print_hi(num_times):
      print(f"We will do this {num_times} times")
  </code></pre>
  
  <p>However, this is most certainly not equivalent to: </p>
  
  <pre><code>print_hi = repeat(print_hi)
  </code></pre>
  
  <p>Because we have the extra argument of <code>num_times</code>. </p>
  
  <p>What am I misunderstanding? 
  Is it equivalent to: </p>
  
  <pre><code>print_hi = repeat(print_hi, num_times=4)
  </code></pre>