To inspect what attributes/methods are in any object
import requests
dir(requests)
<https://docs.python.org/2/library/functions.html#dir>
Alternatively if you are looking for a specific method to exist for an object:
<https://docs.python.org/2/reference/datamodel.html#object.__getattr__>
# Decorators take advantage of Python dynamic and deep introspection abilities (but are just syntactic sugar for re-use)
# *args is a pointer to the "non keyword arguments" aka positional argument
# **kwargs is a pointer to the "keyword arguments" aka func( name='example' )
def decorator( target ):
def wrapper( *args, **kwargs ):
kwargs.update( {'debug': True} ) # Modify keyword arguments, i.e. enable debug no matter what
print 'Calling function "%s" with arguments %s and keyword arguments %s' % (target.__name__, args, kwargs)
return target( *args, **kwargs )
wrapper.attribute = 1
return wrapper
@decorator
def target( a, b, debug=False ):
if debug:
print '[Debug] I am the target function'
return a+b
class UserHandlers(webapp2.RequestHandler):
# @loggingdebug
@handlervalidation( required=['uid' ] , return_to = '/show_user' )
def display_user( self ):
uid = self.request.get( 'uid' )
users = User.all().filter('id =' , uid ).fetch( limit=1 )
user = users.pop()
self.render( "user_profile.html" , { 'name' : user.name } )
# nesting in order to wrap the decorated method
class Handlervalidation():
def __init__( self , required= [] , return_to = None ):
self.required = required
self.return_to = return_to
def __call__( self , func ):
def wrapper(func_self, *args):
logger.info('BEGIN %s(), %s' % (func.__name__, func_self.request.params)) # could be a second decorator @loggingdebug
if not auth_service.is_valid_session(func_self.request):
func_self.redirect('/login?code=no_auth&return_to=%s' % (self.return_to))
return
for param in required:
val = func_self.request.get(param)
if not val or len(val.strip()) == 0:
info.error('ERROR %s(): %s is required' % (func.__name__, param))
func_self.redirect('/error404?code=bad_input¶m=%s' % (param))
func( func_self , *args )
logger.info('END %s(), %s' % (func.__name__, func_self.request.params))
return wrapper