<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>