Arbitrary dunder attributes (was Re: odd difference calling function from class or instance variable)

Chris Angelico rosuav at gmail.com
Wed Aug 13 10:09:20 EDT 2014


On Wed, Aug 13, 2014 at 11:12 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> Chris Angelico wrote:
>
>> The bound method object stores a reference to the original object (the
>> thing that becomes the first argument to the target function) in
>> __self__ (and the function in __func__). ISTM this ought to be _self
>> (and _func), as it's intended to be private;
>
> Why do you say they are intended to be private? Is that documented
> somewhere, or do you mean that if you designed the system, *you* would have
> intended them to be private? :-)

Good point - the latter :) However, that applies only to the one
leading underscore. Whether they're _self/_func or self/func, they
could be regular attributes without being dunder ones.

>> is it really something
>> that has language-level significance on par with __lt__ and so on?
>
> To be honest, I didn't even know about __self__, but I understood __func__
> to be public. And yes, it should be public: being able to introspect a
> method and find the function it came from is a good thing, and sometimes
> useful.

I stand corrected on the privacy issue. But introspection would be
just as easy if it were called func instead. Picking up Ned's wording:

On Wed, Aug 13, 2014 at 10:11 PM, Ned Batchelder <ned at nedbatchelder.com> wrote:
> This is a crude namespacing: Python can use any name it likes so long as its
> a dunder name, and I can use any name I like, so long as it isn't.

This concept generally applies to Python doing stuff with my class. If
I define a class that I want a built-in function, operator, or
language feature, to work with, I define a dunder attribute (most
often a method) to tie in with that - my class, Python's
functionality.

When Python defines the class, it's free to do whatever it likes with
naming. There are public methods and attributes, named nice and simply
because there's no possibility of collision. The bound method object
is like this; it could easily have any number of simply-named
attributes, and most of us wouldn't even be aware of them, much less
concerned that we now can't use those names. We can't possibly
collide, because this is a completely different class from anything
I'm working with.

Even namedtuple, where it *is* possible to have collisions, doesn't go
dunder - it has single-underscore public members. That's a deliberate
decision to use a namespace other than the normal one of simply-named
members; and dunders weren't used. In the case of __self__ and
__func__, what's the advantage of this tagging?

ChrisA



More information about the Python-list mailing list