Book Excerpt: The Python Standard Library by Example

Acquiring Function Properties for Decorators

Updating the properties of a wrapped callable is especially useful when used in a decorator, since the transformed function ends up with properties of the original “bare” function.

import functools 

def	show_details(name, f): 
      """Show details of a callable object.""" 
      print %s:’ % name 
      print ’ object:’,f 
      print ’ __name__:’, 
      try: 
           print f.__name__ 
      except AttributeError: 
           print ’(no __name__)’ 
      print ’ __doc__’, repr(f.__doc__) 
      print 
      return 

def	simple_decorator(f): 
      @functools.wraps(f)
      def decorated(a=’decorated defaults’, b=1): 
          print ’ decorated:’, (a, b) 
          print ’’,
          f(a, b=b) 
          return 
      return decorated 

def	myfunc(a, b=2): 
     "myfunc() is not complicated" 
      print ’ myfunc:’, (a,b) 
      return 

# The raw function 
show_details(’myfunc’, myfunc) 
myfunc(’unwrapped, default b’) 
myfunc(’unwrapped, passing b’, 3) 
print 

# Wrap explicitly 
wrapped_myfunc = simple_decorator(myfunc) 
show_details(’wrapped_myfunc’, wrapped_myfunc) 
wrapped_myfunc() 
wrapped_myfunc(’args to wrapped’, 4) 
print 

# Wrap with decorator syntax 
@simple_decorator 
def decorated_myfunc(a, b): 
    myfunc(a, b) 
    return 

show_details(’decorated_myfunc’, decorated_myfunc) 
decorated_myfunc() 
decorated_myfunc(’args to decorated’, 4) 

functools provides a decorator, wraps(), that applies update_wrapper() to the decorated function.

$ python functools_wraps.py 


myfunc:
 object: <function myfunc at 0x100da3488>
 __name__: myfunc
 __doc__ ’myfunc() is not complicated’ 

 myfunc: (’unwrapped, default b’, 2)
 myfunc: (’unwrapped, passing b’, 3) 

wrapped_myfunc:
 object: <function myfunc at 0x100da3500>
 __name__: myfunc
 __doc__ ’myfunc() is not complicated’ 

decorated: (’decorated defaults’, 1)
   myfunc: (’decorated defaults’, 1) 
decorated: (’args to wrapped’, 4)
   myfunc: (’args to wrapped’, 4) 

decorated_myfunc:
 object: <function decorated_myfunc at 0x100da35f0>
 __name__: decorated_myfunc
 __doc__ None 

 decorated: (’decorated defaults’, 1)
    myfunc: (’decorated defaults’, 1)
 decorated: (’args to decorated’, 4)
    myfunc: (’args to decorated’, 4) 
______________________

Geek Guide
The DevOps Toolbox

Tools and Technologies for Scale and Reliability
by Linux Journal Editor Bill Childers

Get your free copy today

Sponsored by IBM

Upcoming Webinar
8 Signs You're Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
11am CDT, April 29th
Moderated by Linux Journal Contributor Mike Diehl

Sign up now

Sponsored by Skybot