<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jan 23, 2014 at 11:17 AM, Suresh V. <span dir="ltr"><<a href="mailto:suresh_vv@yahoo.com" target="_blank">suresh_vv@yahoo.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Thursday 23 January 2014 02:22 PM, David Townshend wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Maybe I'm missing something, but what's the use case, and why aren't<br>
plain old decorators suitable?<br>
</blockquote>
<br></div>
May be they are.<br>
<br>
Let us say I want to alter the way the smtplib.SMTP.sendmail method works. I would like it to call a function that I define.I can then add this function to the __before__ attribute of this library function.<br>
<br>
Can this be done with decorators?<br></blockquote><div><br></div><div>Not a decorator, but you can monkey patch it:<br><br></div><div> @wraps(smtplib.SMTP.sendmail)<br></div><div> def sendmail(*args, **kwargs):<br>
</div><div> other_function()<br></div><div> return smtplib.SMPT.sendmail(*args, **kwargs)<br><br></div><div> smtplib.SMTP.sendmail = sendmail<br><br></div><div>But I still don't see a good reason for using __before__ rather than the above, other than slightly less typing. In a specific project there might be a lot of this going on and brevity would be justifiable, but in that case writing your own decorator is easy enough.<br>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
<br>
On Thu, Jan 23, 2014 at 10:31 AM, Suresh V.<br>
<<a href="mailto:suresh_vv@yahoo.com" target="_blank">suresh_vv@yahoo.com</a><br></div><div class="im">
<mailto:<a href="mailto:suresh_vv@yahoo.com" target="_blank">suresh_vv@yahoo.com</a>>> wrote:<br>
<br>
Nicely done :-)<br>
<br>
"foo" may come from a library or something, so rather than a<br>
decorator we may have to monkey patch it. Unless there is a nicer<br>
solution.<br>
<br>
Will functools be a good place for something like this?<br>
<br>
<br>
On Thursday 23 January 2014 01:50 PM, Chris Angelico wrote:<br>
<br>
On Thu, Jan 23, 2014 at 7:11 PM, Suresh V.<br>
<<a href="mailto:suresh_vv@yahoo.com" target="_blank">suresh_vv@yahoo.com</a><br></div><div class="im">
<mailto:<a href="mailto:suresh_vv@yahoo.com" target="_blank">suresh_vv@yahoo.com</a>>> wrote:<br>
<br>
On Thursday 23 January 2014 01:22 PM, Chris Angelico wrote:<br>
<br>
<br>
On Thu, Jan 23, 2014 at 6:20 PM, Suresh V.<br>
<<a href="mailto:suresh_vv@yahoo.com" target="_blank">suresh_vv@yahoo.com</a><br></div><div><div class="h5">
<mailto:<a href="mailto:suresh_vv@yahoo.com" target="_blank">suresh_vv@yahoo.com</a>>> wrote:<br>
<br>
<br>
Can we add these two attributes for every<br>
function/method where each is a<br>
list of callables with the same arguments as the<br>
function/method itself?<br>
<br>
Pardon me if this has been discussed before.<br>
Pointers to past discussions<br>
(if any) appreciated.<br>
<br>
<br>
<br>
I'm not exactly sure what you're looking for here. What<br>
causes a<br>
callable to be added to a function's __before__ list,<br>
and/or what will<br>
be done with it?<br>
<br>
<br>
<br>
These are modifiable attributes, so something can be<br>
added/deleted from the<br>
__before__ or __after__ lists.<br>
<br>
<br>
<br>
If you mean that they'll be called before and after the<br>
function<br>
itself, that can be more cleanly done with a decorator.<br>
<br>
<br>
<br>
Yes. Each item in the list will be called in order<br>
immediately before/after<br>
each invocation of the function. This is kinda like<br>
decorators, but more<br>
flexible and simpler. Scope for abuse may be higher too :-)<br>
<br>
<br>
def prepostcall(func):<br>
def wrapper(*args,**kwargs):<br>
for f in wrapper.before: f(*args,**kwargs)<br>
ret = func(*args,**kwargs)<br>
for f in wrapper.after: f(*args,**kwargs)<br>
return ret<br>
wrapper.before = []<br>
wrapper.after = []<br>
return wrapper<br>
<br>
@prepostcall<br>
def foo(x,y,z):<br>
return x*y+z<br>
<br>
foo.before.append(lambda x,y,z: print("Pre-call"))<br>
foo.after.append(lambda x,y,z: print("Post-call"))<br>
<br>
Now just deal with the question of whether the after functions<br>
should<br>
be called if the wrapped function throws :)<br>
<br>
<br>
<br>
<br>
<br>
ChrisA<br></div></div>
______________________________<u></u>___________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<mailto:<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.<u></u>org</a>><br>
<a href="https://mail.python.org/__mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/__<u></u>mailman/listinfo/python-ideas</a><br>
<<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/<u></u>mailman/listinfo/python-ideas</a>><br>
Code of Conduct: <a href="http://python.org/psf/__codeofconduct/" target="_blank">http://python.org/psf/__<u></u>codeofconduct/</a><br>
<<a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/<u></u>codeofconduct/</a>><br>
<br>
<br>
<br>
______________________________<u></u>___________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<mailto:<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.<u></u>org</a>><br>
<a href="https://mail.python.org/__mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/__<u></u>mailman/listinfo/python-ideas</a><br>
<<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/<u></u>mailman/listinfo/python-ideas</a>><br>
Code of Conduct: <a href="http://python.org/psf/__codeofconduct/" target="_blank">http://python.org/psf/__<u></u>codeofconduct/</a><div class="im"><br>
<<a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/<u></u>codeofconduct/</a>><br>
<br>
<br>
<br>
<br>
______________________________<u></u>_________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/<u></u>mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/<u></u>codeofconduct/</a><br>
<br>
</div></blockquote><div class="HOEnZb"><div class="h5">
<br>
<br>
______________________________<u></u>_________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/<u></u>mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/<u></u>codeofconduct/</a><br>
</div></div></blockquote></div><br></div></div>