"Private" Member Variables

Isaac To kkto at csis.hku.hk
Fri May 28 22:09:20 EDT 2004


>>>>> "Scott" == Scott Brady Drummonds <scott.b.drummonds.nospam at intel.com> writes:

    Scott> The problems that arise from directly relying on the member
    Scott> variable in C++ (compile-time type dependency, as I said above)
    Scott> don't exist in Python.  So why provide an accessor at all?  Why
    Scott> not just allow direct reading and writing of the member variable?
    Scott> Is there something here I'm missing?

    Scott> What are your thoughts?  How much privacy should I build into my
    Scott> code?  Should I be using variables beginning with "__" and
    Scott> accessors?  Or is that simply not necessary (or normal) in Python
    Scott> code?

The "__" convention is not about hiding, which, as others has noted, need
not exist anyway.  See an example first:

>>> class C:
...   def value(self):
...     return self.__value
...   def setvalue(self, val):
...     self.__value = val
... 
>>> c = C()
>>> c.setvalue(5)
>>> c.value()
5
>>> c.__value
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: C instance has no attribute '__value'
>>> dir(c)
['_C__value', '__doc__', '__module__', 'setvalue', 'value']
>>> c._C__value
5
>>> c._C__value = 10
>>> c.value()
10

Now it should be clear that the outside can still access the __value within
c, although it has to be named a bit differently: _C__value.  So the "__"
doesn't prevent others from accessing the field.

"__" is important for classes that simultaneously are (1) changing, and (2)
inherited by someone else.  It solves a namespace issue.  Suppose you are
write a class C, give it to your friend, who derive another class D from it.
In the process of deriving, your friend needs to add a collection of fields
into C.  Of course, he reads the documentation of C and, like the above, the
dir() of it to see what field names to avoid.  He thus derives a correct
class D from C.

But you know nothing about it.  In particular, you don't know what fields
are used by your friend.  You continue modify your class to improve it, and
in doing so you need to create additional private fields.  Being private,
you don't document them.  Then you give the class to your friend, who read
the documentation, see nothing intrusive, and use it as a plug-in
replacement of D.  Unluckily, your friend won't know that the fields of your
new C actually clash with the fields of D, and when the class is in use it
gives strange behaviour, giving them a hard time debugging.

A simple technique would resolve the issue: use a naming scheme that says
"this is field f of class C".  So you would name the field like "C_f"
instead of "f".  But when the class name and the field name are long, this
is not an attractive solution.  The "__" trick give you best of both worlds:
you avoid name clashing, and at the same time you don't need to write long
names.  And as a further benefit it is fully standardized, so you don't need
to worry that the third programmer would use a different naming convention.

Regards,
Isaac.



More information about the Python-list mailing list