<div dir="ltr"><br><br>On Sunday, October 5, 2014 5:43:33 PM UTC-4, Guido van Rossum wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr"><div><div><div>This is a clever idea but I doubt it's worth adding.<br><br>The pattern proposed in the example in the first post doesn't strike me as very readable -- though you don't give any examples of *using* the decorator from the example, so it's a little difficult to imagine what the use case would be.<br></div></div></div></div></blockquote><div><br></div><div>The idea is that I have a caller who is making changes to a network of nodes in steps.  The caller tells the link to do phase 1, then makes some changes, then tells the link to do phase 2, then makes some changes, etc.  Each time, the link can memoize some values from the network, send signals, etc.  Therefore, I did not want to have the phases be different methods since the memos would then have to be stored on the object.  Instead the phases are implemented using the generator pattern (that is, each phase is separated by yield) and the caller simply iterates over the generator as it makes its changes. The problem is that in addition to what is implemented by the method, the method wants to also delegate to super.  So we need to iterate over the generator returned by the superclass.  This pattern is easy to follow, but it would be nice to wrap that up in a decorator so that the method-writer can forget about this detail. </div><div> </div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr"><div><div>Adding __parent__ would have to happen as an extra pass once the class is defined -- the decorator (at least its outer part) runs at the time that the method is being defined as a plain function object, and at that time the class object hasn't been created yet. This also means that some decorators can't use the __parent__ attribute (because the outer function of the decorator runs before the object to be stored in __parent__ has been created).<br></div></div></div></blockquote><div><br></div><div>Couldn't __parent__ be filled in when the class is complete by the default metaclass (is that just "type"?)  The generator doesn't need to actually do anything with the parent member.  The lookup is happening in the created method, so I think that's at call time, at which point the attribute will be filled in.  I could have done the same thing with qualname, right?</div><div> <br></div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr"><div><div><br></div>If you really want to explore this idea further, you can probably define a metaclass that adds a __parent__ attribute to the function objects in the class __dict__ when the class is being created. Then you can experiment with using the pattern in some real code. Please report back here with some examples where the presence of __parent__ lets you write cleaner code.<br></div></div></blockquote><div><br></div><div>The problem is that such a metaclass would add the member to the decorated method, and unfortunately, methods and functions don't have access to themselves and their attribtes at runtime as far as I know.  So I'd have to look inside the members and add the __parent__ attribute to "method" attributes of the decorated methods, which is a bit weird.   </div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr"><div><br></div>An alternative that wouldn't even require a metaclass would be to write a helper function that looks the class object up by name after parsing __qualname__. There are some limitations to this, e.g. classes defined inside functions -- but that's already a suspect pattern anyway.<br></div></blockquote><div><br></div><div>Yes, that works, but it really is very ugly to parse a string and then eval it.</div><div> </div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr"><div><br></div></div><div><br><div class="gmail_quote">On Sun, Oct 5, 2014 at 2:18 PM, Neil Girdhar <span dir="ltr"><<a href="javascript:" target="_blank" gdf-obfuscated-mailto="kxRyhfAsij8J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">miste...@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div><br><div class="gmail_quote"><span>On Sun, Oct 5, 2014 at 5:11 PM, Benjamin Peterson <span dir="ltr"><<a href="javascript:" target="_blank" gdf-obfuscated-mailto="kxRyhfAsij8J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">benj...@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Neil Girdhar <mistersheik@...> writes:<br>
<br>
><br>
><br>
><br>
> On Sun, Oct 5, 2014 at 2:09 PM, Benjamin Peterson <benjamin <at><br>
<a href="http://python.org" target="_blank" onmousedown="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org\46sa\75D\46sntz\0751\46usg\75AFQjCNF558DEk4MojQmCDwPIrITw2rjEQA';return true;" onclick="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org\46sa\75D\46sntz\0751\46usg\75AFQjCNF558DEk4MojQmCDwPIrITw2rjEQA';return true;">python.org</a>> wrote:<br>
<span>> Neil Girdhar <mistersheik <at> ...> writes:<br>
> ><br>
> > Many classes, functions, and modules are defined within the context of<br>
> another class, function, or module thereby forming a mathematical forest of<br>
> declarations.  It is possible to walk the descendants using __dict__ (for<br>
> classes and modules), but not the ancestors.  I propose adding __parent__<br>
> that would be filled at the same time that __qualname__ is filled in.This<br>
is unlikely to work.<br>
> 1) It turns basically everything into a cycle.<br>
><br>
><br>
> Why a cycle? <br>
<br>
</span>Because, for example, the class would reference methods, which would<br>
reference the class.<br></blockquote><div><br></div></span><div>Right.  I don't see what's wrong with that.  This already happens with the __module__ member and the module's immediate children.</div><span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span><br>
><br>
><br>
> 2) __qualname__ is determined strictly from syntax, whereas __parent__ could<br>
> not be. For example, what happens if I take a method from one class and set<br>
> it on another? __parent__ would not be well-defined.<br>
><br>
><br>
> I'm suggesting that parent be determined purely from declaration.  If you<br>
copy something, neither qualname nor parent would change unless you change<br>
them. <br>
<br>
</span>It would mean your trick with super would only work for some methods.<br></blockquote><div><br></div></span><div>It would only work for that are decorated in the usual way using @blah on methods defined in the class.  If someone wants to copy that method somewhere else then they'll have to update __parent__ themselves.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div><span><br>
<br>
<br>
______________________________<wbr>_________________<br>
Python-ideas mailing list<br>
<a href="javascript:" target="_blank" gdf-obfuscated-mailto="kxRyhfAsij8J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">Python...@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank" onmousedown="this.href='https://www.google.com/url?q\75https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-ideas\46sa\75D\46sntz\0751\46usg\75AFQjCNFj1EaNHnVmh20FnFPoUi4J-MpfQw';return true;" onclick="this.href='https://www.google.com/url?q\75https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-ideas\46sa\75D\46sntz\0751\46usg\75AFQjCNFj1EaNHnVmh20FnFPoUi4J-MpfQw';return true;">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank" onmousedown="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org%2Fpsf%2Fcodeofconduct%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNHJOrArSUDKkjrnthO6_CznMzkPsA';return true;" onclick="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org%2Fpsf%2Fcodeofconduct%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNHJOrArSUDKkjrnthO6_CznMzkPsA';return true;">http://python.org/psf/<wbr>codeofconduct/</a><br>
<br></span><span>
--<br>
<br>
---<br>
You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.<br>
To unsubscribe from this topic, visit <a href="https://groups.google.com/d/topic/python-ideas/94fTkAkjhCo/unsubscribe" target="_blank" onmousedown="this.href='https://groups.google.com/d/topic/python-ideas/94fTkAkjhCo/unsubscribe';return true;" onclick="this.href='https://groups.google.com/d/topic/python-ideas/94fTkAkjhCo/unsubscribe';return true;">https://groups.google.com/d/<wbr>topic/python-ideas/<wbr>94fTkAkjhCo/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="kxRyhfAsij8J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">python-ideas...@<wbr>googlegroups.com</a>.<br>
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/<wbr>optout</a>.<br>
</span></div></div></blockquote></div><br></div></div>
<br>______________________________<wbr>_________________<br>
Python-ideas mailing list<br>
<a href="javascript:" target="_blank" gdf-obfuscated-mailto="kxRyhfAsij8J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">Python...@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank" onmousedown="this.href='https://www.google.com/url?q\75https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-ideas\46sa\75D\46sntz\0751\46usg\75AFQjCNFj1EaNHnVmh20FnFPoUi4J-MpfQw';return true;" onclick="this.href='https://www.google.com/url?q\75https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-ideas\46sa\75D\46sntz\0751\46usg\75AFQjCNFj1EaNHnVmh20FnFPoUi4J-MpfQw';return true;">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank" onmousedown="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org%2Fpsf%2Fcodeofconduct%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNHJOrArSUDKkjrnthO6_CznMzkPsA';return true;" onclick="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org%2Fpsf%2Fcodeofconduct%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNHJOrArSUDKkjrnthO6_CznMzkPsA';return true;">http://python.org/psf/<wbr>codeofconduct/</a><br></blockquote></div><br><br clear="all"><br>-- <br>--Guido van Rossum (<a href="http://python.org/~guido" target="_blank" onmousedown="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org%2F~guido\46sa\75D\46sntz\0751\46usg\75AFQjCNGKI5lSgzXFUM7Y5HtkFAp6sQAxEg';return true;" onclick="this.href='http://www.google.com/url?q\75http%3A%2F%2Fpython.org%2F~guido\46sa\75D\46sntz\0751\46usg\75AFQjCNGKI5lSgzXFUM7Y5HtkFAp6sQAxEg';return true;">python.org/~guido</a>)
</div>
</blockquote></div>