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