PEP Idea: Real private attribute

Mehrzad Saremi mehrzad.1024 at gmail.com
Sat Aug 28 10:31:38 EDT 2021


Python currently uses name mangling for double-underscore attributes. Name
mangling is not an ideal method to avoid name conflicting. There are
various normal programming patterns that can simply cause name conflicting
in double-underscore members. A typical example is when a class is
re-decorated using the same decorator. The decorator can not take
double-underscore members without name conflicts. For example:

```
@custom_decorator("a")
@custom_decorator("b")
class C:
    pass
```

The `@custom_decorator` wrapper may need to hold private members, but
Python's current name conflict resolution does not provide any solution and
the decorator cannot hold private members without applying tricky
programming methods.

Another example is when a class inherits from a base class of the same name.

```
class View:
    """A class representing a view of an object; similar to
numpy.ndarray.view"""
    pass

class Object:
    class View(View):
        """A view class costumized for objects of type Object"""
        pass
```

Again, in this example, class `Object.View` can't take double-underscore
names without conflicting with `View`'s.

My idea is to introduce real private members (by which I do not mean to be
inaccessible from outside the class, but to be guaranteed not to conflict
with other private members of the same object). These private members are
started with triple underscores and are stored in a separate dictionary
named `__privs__`. Unlike `__dict__` that takes 'str' keys, `__privs__`
will be a double layer dictionary that takes 'type' keys in the first
level, and 'str' keys in the second level.

For example, assume that the user runs the following code:
```
class C:
    def __init__(self, value):
        self.___member = value

c = C("my value")
```

On the last line, Python's attribute setter creates a new entry in the
dictionary with key `C`, adds the value "my value" to a new entry with the
key 'member'.

The user can then retrieve `c.___member` by invoking the `__privs__`
dictionary:

```
print(c.__privs__[C]['member'])  # prints 'my value'
```

Note that, unlike class names, class objects are unique and there will not
be any conflicts. Python classes are hashable and can be dictionary keys.
Personally, I do not see any disadvantage of using __privs__ over name
mangling/double-underscores. While name mangling does not truly guarantee
conflict resolution, __privs__ does.

Please discuss the idea, let me know what you think about it, whether there
are possible disadvantages, and if you think it will be approved as a PEP.

Thanks,
Mehrzad Saremi

AI M.Sc. grad. from AUT


More information about the Python-list mailing list