[Python-ideas] Fwd: Define a method or function attribute outside of a class with the dot operator

Nick Coghlan ncoghlan at gmail.com
Fri Feb 10 12:20:03 EST 2017

On 10 February 2017 at 16:25, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sat, Feb 11, 2017 at 01:25:40AM +1100, Chris Angelico wrote:
>> For what it's worth, my answers would be:
>> __name__ would be the textual representation of exactly what you typed
>> between "def" and the open parenthesis. __qualname__ would be built
>> the exact same way it currently is, based on that __name__.
> If I'm reading this right, you want this behaviour:
> class Spam:
>     pass
> def Spam.func(self): pass
> assert 'Spam.func' not in Spam.__dict__
> assert 'func' in Spam.__dict__
> assert Spam.func.__name__ == 'Spam.func'
> assert Spam.func.__qualname__ == 'Spam.Spam.func'
> If that's the case, I can only ask... what advantage do you see from
> this? Because I can see plenty of opportunity for confusion, and no
> advantage.

What I would personally hope to see from the proposal is that given:

    class Spam:

    def Spam.func(self):
        return __class__

the effective runtime behaviour would be semantically identical to:

    class Spam:
        def func(self):
            return __class__

such that:

  * __name__ is set based on the method name after the dot
  * __qualname__ is set based on the __name__ of the given class
  * __set_owner__ is called after any function decorators are applied
  * zero-argument super() and other __class__ references work properly
from the injected method

Potentially, RuntimeError could be raised if the reference before the
dot is not to a type instance.

If it *doesn't* do that, then I'd be -1 on the proposal, since it
doesn't add enough expressiveness to the language to be worth the
extra syntax. By contrast, if it *does* do it, then it makes class
definitions more decomposable, by providing post-definition access to
parts of the machinery that are currently only accessible during the
process of defining the class.

The use case would be to make it easier to inject descriptors when
writing class decorators such that they behave essentially the same as
they do when defined in the class body:

    def my_class_decorator(cls):
        def cls.injected_method(self):
            # Just write injected methods the same way you would in a class body
            return __class__
        return cls

(Actually doing this may require elevating super and __class__ to true
keyword expressions, rather than the pseudo-keywords they are now)


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list