<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Feb 10, 2017 at 9:20 AM, Nick Coghlan <span dir="ltr"><<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">What I would personally hope to see from the proposal is that given:<br>
<span class="gmail-"><br>
    class Spam:<br>
        pass<br>
<br>
    def Spam.func(self):<br>
</span>        return __class__<br>
<br>
the effective runtime behaviour would be semantically identical to:<br>
<br>
    class Spam:<br>
        def func(self):<br>
            return __class__<br></blockquote><div><br></div><div>Yes, this is exactly what I would hope/expect to see.</div><div><br></div><div>One use case for this functionality is defining classes with an extensive method-based API with a sane dependency graph. For example, consider writing a class like <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html">numpy.ndarray</a> or <a href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html">pandas.DataFrame</a> with dozens of methods. You could argue that using so many methods is an anti-pattern, but nonetheless it's pretty common and hard to avoid in some cases (e.g., for making number-like classes that support arithmetic and comparisons).</div><div><br></div><div>For obvious reasons, the functionality for these classes does not all live in a single module. But the modules that define helper functions for most methods also depend on the base class, so many of them need to get <a href="https://github.com/pandas-dev/pandas/blob/v0.19.2/pandas/core/frame.py#L1227">imported inside method definitions</a> to avoid circular imports. The result is pretty ugly, and files defining the class still get gigantic.</div><div><br></div><div>An important note is that ideally, we would still have way of indicating that Spam.func should exists in on the Spam class itself, even if it doesn't define the implementation. I suppose an abstractmethod overwritten by the later definition might do the trick, e.g.,<br></div><div><br></div><div>class Spam(metaclass=ABCMeta):</div><div>    @abstractmethod<br></div><div>    def func(self):</div><div>        pass</div><div><br></div><div>def Spam.func(self):</div><div>    return __class__</div><div><br></div><div>And finally, it's quite possible that there's a clean metaclass based solution for extending Spam in another file, I just don't know it yet.</div><div><br></div></div></div></div>