class-private names and the Zen of Python

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue Oct 8 09:24:10 EDT 2013


On Tue, 08 Oct 2013 12:13:48 +0200, Marco Buttu wrote:

> In the following case:
> 
>  >>> class Foo:
> ...     _Foo__a = 100
> ...     __a = 33
> ...
>  >>> Foo._Foo__a
> 33
> 
> I think this behavior, for a user who does not know the convention,
> could be a surprise. 

Yes, you are correct. It surprised me, and I've been using Python for 
more than 15 years, and I know the convention of double-underscore name-
mangling.


> Should be raising an exception (in order to inform
> the user the transformation of the name __a have been replaced an
> existing name) a possible --explicit-- alternative?

No, I don't think so. That would slow down class creation, for no real 
benefit. Except for the name-mangling part, this is no different from:

class Spam:
    x = 23
    x = 42

If anything, something like PyLint or PyChecker could warn about it. But 
the language itself is fine like it is.


> Another question is: where is the place in which this transformation
> occurs? Is it at the parser level, before the dictionary attribute is
> gave as argument to the metaclass?

Good question!

I don't have a full answer, but I have a part answer: it occurs before 
the metaclass sees the namespace:

py> class Meta(type):
...     def __new__(meta, name, bases, namespace):
...             print(namespace)
...             return super().__new__(meta, name, bases, namespace)
...
py>
py> class Test(metaclass=Meta):
...     __test = 'foo'
...
{'__module__': '__main__', '_Test__test': 'foo', '__qualname__': 'Test'}


so I think it is done by the parser.



-- 
Steven



More information about the Python-list mailing list