Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #8585
| Date | 2011-06-29 14:29 -0700 |
|---|---|
| From | Ethan Furman <ethan@stoneleaf.us> |
| 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> |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.511.1309382125.1164.python-list@python.org> (permalink) |
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 | Next — Previous in thread | Next in thread | Find similar | Unroll 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