1. 2010
    Aug
    07

    More Python voodoo: optional-argument decorators

    I’ve just been doing something that probably should never be done in Python (again), and I figured it might be useful to record this little snippet for posterity. Many Python programmers are probably familiar with decorators, which modify functions by wrapping them with other functions. For example, if you want to print ‘entering’ and ‘exiting’ to trace when a function’s execution begins and ends, you could do that with a decorator:

    def trace(func):
        def wrapper(*args, **kwargs):
            print 'entering'
            func(*args, **kwargs)
            print 'exiting'
        return wrapper
    
    @trace
    def f(a,b):
         print 'in f: ' + str(a) + ',' + str(b)
    

    Note that in practice there are better ways to do this, but it’s just an example.

    Anyway, it’s also possible to customize the behavior of decorator itself by providing arguments, for instance if you wanted to print different strings instead of ‘entering’ and ‘exiting’. But in that case, your “decorator” function is actually a wrapper that creates the real decorator and returns it:

    def trace(enter_string, exit_string):
        def _trace(func):
            def wrapper(*args, **kwargs):
                print enter_string
                func(*args, **kwargs)
                print exit_string
            return wrapper
        return _trace
    
    @trace('calling f', 'returning')
    def f(a,b):
         print 'in f: ' + str …
  2. 2009
    Jul
    27

    More Python voodoo: combination class/instance methods

    Here’s a neat tidbit from my website code: Let’s say you’re writing a class, and you want it to have some methods that can be called as either class or instance methods. Of course, you can do it by writing a class method, but if you want the method to be able to use instance attributes when it’s called on an instance, you can do it using a descriptor. Here’s how.