Using decorators with argument in Python

Ethan Furman ethan at stoneleaf.us
Wed Jun 29 15:30:50 EDT 2011


John Posner wrote:
> Investigating how this fact fit in with the current thread, I came up
> with an alternative to the three levels of "def" (pronounced "three
> levels of death"). Following is code for two decorators:
> 
> * the first one encloses the output of a function with lines of "#"
> characters, and is used like this:
> 
>      @enclose
>      myfun(...
> 
> * the second one encloses the output of a function with lines of a
> user-specified character, and is used like this:
> 
>      @enclose("&")
>      myfun(...
> 
> Here's the Python2 code for each one:

[snippety-snip]

How about just having one bit of code that works either way?

8<------------------------------------------------------------------
class enclose(object):
     def __init__(self, char='#'):
         self.char = char
         if callable(char):  # was a function passed in directly?
             self.char = '#' # use default char
             self.func = char
     def __call__(self, func=None):
         if func is None:
             return self._call()
         self.func = func
         return self
     def _call(self):
         print("\n" + self.char * 50)
         self.func()
         print(self.char * 50 + '\n')

if __name__ == '__main__':
     @enclose
     def test1():
         print('Spam!')

     @enclose('-')
     def test2():
         print('Eggs!')

     test1()
     test2()
8<------------------------------------------------------------------

Output:

##################################################
Spam!
##################################################


--------------------------------------------------
Eggs!
--------------------------------------------------

8<------------------------------------------------------------------


~Ethan~



More information about the Python-list mailing list