Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Protected" access in Python - how?

I would like to set up a class hierarchy in Python 3.2 with 'protected' access: Members of the base class would be in scope only for derived classes, but not 'public'.

A double underscore makes a member 'private', a single underscore indicates a warning but the member remains 'public'. What (if any...) is the correct syntax for designating a 'protected' member.

like image 735
Vector Avatar asked Feb 24 '13 06:02

Vector


People also ask

How do I access protected data in Python?

Protected variables are those data members of a class that can be accessed within the class and the classes derived from that class. In Python, there is no existence of “Public” instance variables. However, we use underscore '_' symbol to determine the access control of a data member in a class.

How do you declare private and protected in Python?

To create a private variable, you need to prefix double underscores with the name of the variable. To create a protected variable, you need to prefix a single underscore with the variable name.

How Python represents the private and protected access specifiers?

Solution. Private members of a class are denied access from the outside of the class. They can be handled only within the class. Protected members of a class are accessible from within the class and are also available to its sub-classes.

How do you access a private variable in Python?

In Python, there is no existence of “Private” instance variables that cannot be accessed except inside an object.


2 Answers

Member access allowance in Python works by "negotiation" and "treaties", not by force.

In other words, the user of your class is supposed to leave their hands off things which are not their business, but you cannot enforce that other than my using _xxx identifiers making absolutely clear that their access is (normally) not suitable.

like image 119
glglgl Avatar answered Nov 01 '22 23:11

glglgl


Double underscores don't make a member 'private' in the C++ or Java sense - Python quite explicitly eschews that kind of language-enforced access rules. A single underscore, by convention, marks an attribute or a method as an "implementation detail" - that is, things outside can still get to it, but this isn't a supported part of the class' interface and, therefore, the guarantees that the class might make about invariants or back/forwards compatibility no longer apply. This solves the same conceptual problem as 'private' (separation of interface and implementation) in a different way.

Double underscores invoke name mangling which still isn't 'private' - it is just a slightly stronger formulation of the above, whereby: - This function is an implementation detail of this class, but - Subclasses might reasonably expect to have a method of the same name that isn't meant as an overridden version of the original

This takes a little bit of language support, whereby the __name is mangled to include the name of the class - so that subclass versions of it get different names instead of overriding. It is still quite possible for a subclass or outside code to call that method if it really wants to - and the goal of name mangling is explicitly not to prevent that.

But because of all this, 'protected' turns out not to make much sense in Python - if you really have a method that could break invariants unless called by a subclass (and, realistically, you probably don't even if you think you do), the Python Way is just to document that. Put a note in your docstring to the effect of "This is assumed to only be called by subclasses", and run with the assumption that clients will do the right thing - because if they don't, it becomes their own problem.

like image 21
lvc Avatar answered Nov 01 '22 22:11

lvc