[Python-ideas] __before__ and __after__ attributes for functions

David Mertz mertz at gnosis.cx
Thu Jan 23 19:14:39 CET 2014


On Thu, Jan 23, 2014 at 12:31 AM, Suresh V. <suresh_vv at yahoo.com> wrote:

> Nicely done :-)
> "foo" may come from a library or something, so rather than a decorator we
> may have to monkey patch it. Unless there is a nicer solution.
> Will functools be a good place for something like this?


Not really monkey patching.  Just:

from library import foo
@prepostcall
def foo(*args, **kws):
    return foo(*args, **kws)

It's just rebinding the name 'foo' with the decorator.



>
>
> On Thursday 23 January 2014 01:50 PM, Chris Angelico wrote:
>
>> On Thu, Jan 23, 2014 at 7:11 PM, Suresh V. <suresh_vv at yahoo.com> wrote:
>>
>>> On Thursday 23 January 2014 01:22 PM, Chris Angelico wrote:
>>>
>>>>
>>>> On Thu, Jan 23, 2014 at 6:20 PM, Suresh V. <suresh_vv at yahoo.com> wrote:
>>>>
>>>>>
>>>>> Can we add these two attributes for every function/method where each
>>>>> is a
>>>>> list of callables with the same arguments as the function/method
>>>>> itself?
>>>>>
>>>>> Pardon me if this has been discussed before. Pointers to past
>>>>> discussions
>>>>> (if any) appreciated.
>>>>>
>>>>
>>>>
>>>> I'm not exactly sure what you're looking for here. What causes a
>>>> callable to be added to a function's __before__ list, and/or what will
>>>> be done with it?
>>>>
>>>
>>>
>>> These are modifiable attributes, so something can be added/deleted from
>>> the
>>> __before__ or __after__ lists.
>>>
>>>
>>>
>>>> If you mean that they'll be called before and after the function
>>>> itself, that can be more cleanly done with a decorator.
>>>>
>>>
>>>
>>> Yes. Each item in the list will be called in order immediately
>>> before/after
>>> each invocation of the function. This is kinda like decorators, but more
>>> flexible and simpler. Scope for abuse may be higher too :-)
>>>
>>
>> def prepostcall(func):
>>      def wrapper(*args,**kwargs):
>>          for f in wrapper.before: f(*args,**kwargs)
>>          ret = func(*args,**kwargs)
>>          for f in wrapper.after: f(*args,**kwargs)
>>          return ret
>>      wrapper.before = []
>>      wrapper.after = []
>>      return wrapper
>>
>> @prepostcall
>> def foo(x,y,z):
>>      return x*y+z
>>
>> foo.before.append(lambda x,y,z: print("Pre-call"))
>> foo.after.append(lambda x,y,z: print("Post-call"))
>>
>> Now just deal with the question of whether the after functions should
>> be called if the wrapped function throws :)
>>
>>
>
>
>
>  ChrisA
>> _______________________________________________
>> Python-ideas mailing list
>> Python-ideas at python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140123/99c2d66f/attachment.html>


More information about the Python-ideas mailing list