Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #8585

Re: Using decorators with argument in Python

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!selfless.tophat.at!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail
Return-Path <ethan@stoneleaf.us>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'args': 0.05; 'subject:Python': 0.06; 'char': 0.07; '__name__': 0.09; 'decorator': 0.09; 'from:addr:ethan': 0.09; 'from:addr:stoneleaf.us': 0.09; 'from:name:ethan furman': 0.09; 'func': 0.09; 'message-id:@stoneleaf.us': 0.09; 'none:': 0.09; 'quickly.': 0.09; 'received:gator410.hostgator.com': 0.09; '~ethan~': 0.09; 'syntax': 0.11; 'wed,': 0.12; 'wrote:': 0.15; "'\\n')": 0.16; "'__main__':": 0.16; '**kwargs)': 0.16; '**kwargs):': 0.16; '*args,': 0.16; '50)': 0.16; 'callable,': 0.16; 'received:72.11': 0.16; 'received:72.11.125': 0.16; 'received:72.11.125.166': 0.16; 'argument': 0.16; 'cc:addr:python- list': 0.16; 'pm,': 0.16; 'def': 0.16; 'written': 0.17; 'example.': 0.19; 'cc:2**0': 0.21; 'cc:no real name:2**0': 0.22; 'header:In-Reply-To:1': 0.22; 'optional': 0.23; 'way?': 0.23; 'code': 0.24; 'keyword': 0.25; 'function': 0.26; 'depends': 0.28; 'bit': 0.28; 'cc:addr:python.org': 0.30; 'kelly': 0.30; 'class': 0.31; 'least': 0.31; "won't": 0.32; 'header:User-Agent:1': 0.34; 'none': 0.35; 'skip:@ 10': 0.35; 'pretty': 0.35; 'passed': 0.37; 'takes': 0.38; 'subject:: ': 0.38; 'two': 0.38; 'case': 0.39; 'either': 0.39; 'subject:with': 0.39; 'course.': 0.63; 'received:websitewelcome.com': 0.65; 'adapt': 0.67; 'discipline': 0.67; 'received:184': 0.67; 'bright': 0.84; 'directly?': 0.84
Date Wed, 29 Jun 2011 14:29:45 -0700
From Ethan Furman <ethan@stoneleaf.us>
User-Agent Thunderbird 1.5.0.10 (Windows/20070221)
MIME-Version 1.0
To Ian Kelly <ian.g.kelly@gmail.com>
Subject Re: Using decorators with argument in Python
References <d35e1e82-410b-471b-a3c7-379c1822adb0@m22g2000yqh.googlegroups.com> <4e0a0a8b$1@dnews.tpgi.com.au> <4E0B5F7C.7030802@codicesoftware.com> <4E0B7D6A.1080404@stoneleaf.us> <BANLkTimW4=Gdvfh4d5sD-Phzo8qJUuXbrw@mail.gmail.com>
In-Reply-To <BANLkTimW4=Gdvfh4d5sD-Phzo8qJUuXbrw@mail.gmail.com>
Content-Type text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding 7bit
X-AntiAbuse This header was added to track abuse, please include it with any abuse report
X-AntiAbuse Primary Hostname - gator410.hostgator.com
X-AntiAbuse Original Domain - python.org
X-AntiAbuse Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse Sender Address Domain - stoneleaf.us
X-BWhitelist no
X-Source
X-Source-Args
X-Source-Dir
X-Source-Sender mail.admailinc.com ([192.168.10.136]) [72.11.125.166]:1896
X-Source-Auth ethan+stoneleaf.us
X-Email-Count 1
X-Source-Cap dG9idWs7dG9idWs7Z2F0b3I0MTAuaG9zdGdhdG9yLmNvbQ==
Cc python-list@python.org
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.12
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.511.1309382125.1164.python-list@python.org> (permalink)
Lines 102
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1309382125 news.xs4all.nl 21798 [2001:888:2000:d::a6]:45849
X-Complaints-To abuse@xs4all.nl
Xref x330-a1.tempe.blueboxinc.net comp.lang.python:8585

Show key headers only | View raw


Ian Kelly wrote:
> On Wed, Jun 29, 2011 at 1:30 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
>> How about just having one bit of code that works either way?
> 
> How would you adapt that code if you wanted to be able to decorate a
> function that takes arguments?

8<----------------------------------------------------------------
class enclose(object):
     func = None
     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, *args, **kwargs):
         if self.func is None:
             self.func = func
             return self
         if func is not None:
             args = (func, ) + args
         return self._call(*args, **kwargs)
     def _call(self, *args, **kwargs):
         print("\n" + self.char * 50)
         self.func(*args, **kwargs)
         print(self.char * 50 + '\n')
if __name__ == '__main__':
     @enclose
     def test1():
         print('Spam!')
     @enclose('-')
     def test2():
         print('Eggs!')
     @enclose
     def test3(string):
         print(string)
     @enclose('^')
     def test4(string):
         print(string)
     test1()
     test2()
     test3('Python')
     test4('Rules!  ;)')
8<----------------------------------------------------------------

> This also won't work if the argument to the decorator is itself a
> callable, such as in the OP's example.

Indeed.  In that case you need two keywords to __init__, and the 
discipline to always use the keyword syntax at least for the optional 
function paramater.  On the bright side, if one forgets, it blows up 
pretty quickly.

Whether it's worth the extra effort depends on the programmer's tastes, 
of course.

8<----------------------------------------------------------------
class enclose(object):
     func = None
     pre_func = None
     def __init__(self, dec_func=None, opt_func=None):
         if opt_func is None:
             if dec_func is not None: # was written without ()'s
                 self.func = dec_func
         else:
             self.pre_func = opt_func
     def __call__(self, func=None, *args, **kwargs):
         if self.func is None:
             self.func = func
             return self
         if func is not None:
             args = (func, ) + args
         if self.pre_func is not None:
             self.pre_func()
         return self._call(*args, **kwargs)
     def _call(self, *args, **kwargs):
         print("\n" + '~' * 50)
         self.func(*args, **kwargs)
         print('~' * 50 + '\n')

if __name__ == '__main__':
     def some_func():
         print('some func here')
     @enclose
     def test1():
         print('Spam!')
     @enclose(opt_func=some_func)
     def test2():
         print('Eggs!')
     @enclose
     def test3(string):
         print(string)
     @enclose(opt_func=some_func)
     def test4(string):
         print(string)
     test1()
     test2()
     test3('Python')
     test4('Rules!  ;)')
8<----------------------------------------------------------------

~Ethan~

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Using decorators with argument in Python Jigar Tanna <poisonousrattle5@gmail.com> - 2011-06-28 09:52 -0700
  Re: Using decorators with argument in Python Lie Ryan <lie.1296@gmail.com> - 2011-06-29 03:06 +1000
    Re: Using decorators with argument in Python John Posner <jjposner@codicesoftware.com> - 2011-06-29 13:23 -0400
    Re: Using decorators with argument in Python Ethan Furman <ethan@stoneleaf.us> - 2011-06-29 12:30 -0700
    Re: Using decorators with argument in Python Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-29 13:29 -0600
    Re: Using decorators with argument in Python Ethan Furman <ethan@stoneleaf.us> - 2011-06-29 14:29 -0700
    Re: Using decorators with argument in Python Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-29 15:26 -0600
    Re: Using decorators with argument in Python Ethan Furman <ethan@stoneleaf.us> - 2011-06-29 14:51 -0700
    Re: Using decorators with argument in Python Duncan Booth <duncan.booth@invalid.invalid> - 2011-06-30 09:00 +0000
    Re: Using decorators with argument in Python John Posner <jjposner@codicesoftware.com> - 2011-07-01 11:18 -0400
  Re: Using decorators with argument in Python Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-28 11:20 -0600
  Re: Using decorators with argument in Python Ben Finney <ben+python@benfinney.id.au> - 2011-06-29 08:19 +1000

csiph-web