john pfeiffer
  • Home
  • Categories
  • Tags
  • Archives

decorators on classes introspection dir properties

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&param=%s' % (param))
            func( func_self , *args )
            logger.info('END %s(), %s' % (func.__name__, func_self.request.params))
            return wrapper

  • « redirect a webpage permenantly 301
  • heroku intro virtualenv bitbucket and tdd flask gunicorn »

Published

Nov 6, 2014

Category

python

~224 words

Tags

  • classes 92
  • decorators 1
  • dir 4
  • introspection 1
  • on 26
  • properties 8
  • python 180