Private variables 
Author Message
 Private variables

It is possible in python to get private class members by using names
beginning with 2 underscores, and finished by at least 1 underscore.

I personnally tend to use class member names beginning with one
underscore to indicate that the member is 'internal' and should not
be called by external applications, and from looking at the standard
library source code, it seems that this is more common than the official
way mentionned hereabove.

I would like to hear what the opinion of pythoneers is on that topic.

Please feel free to point me to the list archives if this has already
debated over and over.

Alexandre Fayolle
--
LOGILAB, Paris (France).
http://www.*-*-*.com/   http://www.*-*-*.com/   http://www.*-*-*.com/
Narval, the first software agent available as free software (GPL).



Sun, 29 Feb 2004 17:16:36 GMT  
 Private variables

Quote:
> It is possible in python to get private class members by using names
> beginning with 2 underscores, and finished by at least 1 underscore.

Yes, and not only private *class members*: it also works for
class-private *module-level names*, for example:

class One:
    global __beep
    __beep = 23
    def beep(self): print __beep

class Two:
    global __beep
    __beep = 42
    def beep(self): print __beep

One().beep()
Two().beep()
print dir()

will output:

23
42
['One', 'Two', '_One__beep', '_Two__beep', '__builtins__', '__doc__',
'__name__'
]

Quote:
> I personnally tend to use class member names beginning with one
> underscore to indicate that the member is 'internal' and should not
> be called by external applications, and from looking at the standard
> library source code, it seems that this is more common than the official
> way mentionned hereabove.

> I would like to hear what the opinion of pythoneers is on that topic.

My personal opinion is that __beep style names serve to avoid
accidental clashes of identifiers between base and derived
classes -- you can use that style of identifiers without any
worries about some ancestor or descendant class duplicating
it by accident, and that's the only feature that makes them
really useful.  Inheritance hierarchies (particularly between
classes that are separately developed and released) don't
tend to be very deep in most Python code, so it's not such
a crucial issue in most cases.  But it's nice when it comes
up.  And tends to reassure people coming from languages such
as C++ or Java which seem to think privacy is indispensable:-).

Alex



Sun, 29 Feb 2004 20:11:57 GMT  
 Private variables
[Alexandre Fayolle]

Quote:
> It is possible in python to get private class members by using names
> beginning with 2 underscores, and finished by at least 1 underscore.

You don't need an underscore at the end.  A name in a class is private if
and only if it begins with at least two underscores and does not end with at
least two underscores (names that both begin and end with at least two
underscores are reserved -- like __class__ and __add__ and __init__ and even
__).  So __private and __private_ are both private names, but Python
reserves the right to take __private__ away for its own purposes.

Quote:
> I personnally tend to use class member names beginning with one
> underscore to indicate that the member is 'internal' and should not
> be called by external applications, and from looking at the standard
> library source code, it seems that this is more common than the official
> way mentionned hereabove.

They serve different purposes -- a single leading underscore is merely
advisory, while a private name is also merely advisory <wink> but indicates
you're more serious about it.  Semantically, the single leading underscore
means nothing, so is purely convention.  Private names have a tiny bit of
(easily circumvented, but hard to *accidentally* circumvent) enforcement.
Most of the time Python class authors aren't interested in interfering with
how people want to use their classes, but any leading underscore screams
"use at your own risk".

as-if-you-ever-used-anything-at-anyone-else's-risk<wink>-ly y'rs  - tim



Mon, 01 Mar 2004 04:13:42 GMT  
 Private variables
Actually a member is private if it starts with 2 underscores and does not
end with 2 underscores.  There is no special meaning for a single
terminating underscore.

By convention, starting and ending with double underscore is reserved for
special functions such as __init__ and __add__ (which are not private).

Quote:
>>> class X:

...  def __init__(self):
...   self.__priv = 'spammity'
...
Quote:
>>> x = X()
>>> x.__priv

Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
AttributeError: X instance has no attribute '__priv'
Quote:
>>> x._X__priv

'spammity'

I rarely use private members, and tend to use the single underscore
convention to say that a member is intended to be private.  You could say I
don't really mind giving my users enough rope to shoot themselves in the
foot. :-)

I use true private members when I feel like being extra careful, or when I
want to avoid base class / derived class namespace clashes.

There are some silly people who would claim that python doesn't have private
members at all (and therefore is not object oriented) because the so called
private members are accessible by the _class__attr notation.  All I can say
to such people is "you are silly".  Anyway I can be silly too: it turns out
that C++ is not object oriented either because you can include the
following:

#define private public

I've also heard a particularly bizzare counterargument.  Apparently it is
possible for private to change the relative addresses of member data, so the
above hack is totally unsafe, therefore C++ is object oriented after all.
Huh?

Quote:
----- Original Message -----

Newsgroups: comp.lang.python

Sent: Wednesday, September 12, 2001 2:16 AM
Subject: [Poll] Private variables

> It is possible in python to get private class members by using names
> beginning with 2 underscores, and finished by at least 1 underscore.

> I personnally tend to use class member names beginning with one
> underscore to indicate that the member is 'internal' and should not
> be called by external applications, and from looking at the standard
> library source code, it seems that this is more common than the official
> way mentionned hereabove.

> I would like to hear what the opinion of pythoneers is on that topic.

> Please feel free to point me to the list archives if this has already
> debated over and over.

> Alexandre Fayolle
> --
> LOGILAB, Paris (France).
> http://www.logilab.com   http://www.logilab.fr  http://www.logilab.org
> Narval, the first software agent available as free software (GPL).
> --
> http://mail.python.org/mailman/listinfo/python-list



Mon, 01 Mar 2004 03:27:48 GMT  
 Private variables

Quote:

>[Alexandre Fayolle]
>> It is possible in python to get private class members by using names
>> beginning with 2 underscores, and finished by at least 1 underscore.

>You don't need an underscore at the end.  A name in a class is private if

Wooops. I, of course, meant 'at most 1 underscore'.

Alexandre Fayolle
--
LOGILAB, Paris (France).
http://www.logilab.com   http://www.logilab.fr  http://www.logilab.org
Narval, the first software agent available as free software (GPL).



Mon, 01 Mar 2004 14:53:49 GMT  
 Private variables

Quote:

> My personal opinion is that __beep style names serve to avoid
> accidental clashes of identifiers between base and derived
> classes -- you can use that style of identifiers without any
> worries about some ancestor or descendant class duplicating
> it by accident, and that's the only feature that makes them
> really useful.

Unless you use names like these in your hierarchy:

    Python 2.1 (#1, May  2 2001, 18:27:26)
    [GCC 2.7.2.1] on linux2
    Type "copyright", "credits" or "license" for more information.
    >>> class _A :
    ...   __beep = 1
    ...
    >>> class A(_A) :
    ...   __beep = 2
    ...
    >>> class B(A) :
    ...   __beep = 3
    ...
    >>> dir (_A)
    ['_A__beep', '__doc__', '__module__']
    >>> dir(A)
    ['_A__beep', '__doc__', '__module__']
    >>> dir(B)
    ['_B__beep', '__doc__', '__module__']
    >>>

The name mangling of `__bar` names misbehaves if the class name starts
with a single underscore. To be able to use `__bar` names safely one
has to avoid `_Foo` class names.

This is the only example of accidental feature interaction in Python
that I'm aware of. [It once cost me the better part of a day to figure
out why my program suddenly went catatonic.]

--

Glasauergasse 32                                       Tel: +43 1 876 62 36
A-1130 Vienna, Austria                                 Fax: +43 1 877 66 92



Mon, 01 Mar 2004 13:40:08 GMT  
 Private variables

Quote:

>They serve different purposes -- a single leading underscore is merely
>advisory, while a private name is also merely advisory <wink> but
>indicates you're more serious about it.  Semantically, the single
>leading underscore means nothing, so is purely convention.

That's *almost* true.  The convention comes from the fact that in a
slightly different context, a single leading underscore *does* have
meaning: module attributes with a single leading underscore do not get
imported with "from foo import *".  (Well, this was true until the
__all__ attribute got created, but let's not quibble.)
--

Hugs and backrubs -- I break Rule 6                 http://www.*-*-*.com/
Androgynous poly {*filter*} vanilla {*filter*} het Pythonista  

We must not let the evil of a few {*filter*}le the freedoms of the many.



Thu, 04 Mar 2004 01:46:33 GMT  
 Private variables
[Christian Tanzer]

Quote:
>     Python 2.1 (#1, May  2 2001, 18:27:26)
>     [GCC 2.7.2.1] on linux2
>     Type "copyright", "credits" or "license" for more information.
>     >>> class _A :
>     ...   __beep = 1
>     ...
>     >>> class A(_A) :
>     ...   __beep = 2
>     ...
>     >>> class B(A) :
>     ...   __beep = 3
>     ...
>     >>> dir (_A)
>     ['_A__beep', '__doc__', '__module__']
>     >>> dir(A)
>     ['_A__beep', '__doc__', '__module__']
>     >>> dir(B)
>     ['_B__beep', '__doc__', '__module__']

> The name mangling of `__bar` names misbehaves if the class name starts
> with a single underscore. To be able to use `__bar` names safely one
> has to avoid `_Foo` class names.

> This is the only example of accidental feature interaction in Python
> that I'm aware of.

It's not an accident:  the compiler goes out of its way to remove leading
underscores from class names while mangling, and this behavior is documented
in section 5.2.1 (Identifiers -- Private name mangling) of the Ref Man.

Suppose it didn't do this.  Then the mangled name in _A would be __A_beep,
and in A would (still be) _A_beep.  How then in A would you be able to
access _A's version of beep?  If you typed __A_beep within the scope of A,
it would get mangled to _A__A_beep:  the point of the rule is so that a
mangled name never ever "looks like" a private name, so that in turn you can
always do the mangling by hand (when needed) and not have the compiler
interfere.

You could protest that if you *wanted* to access _A's beep from within A you
never would have made it a private name to begin with -- but Guido knows you
don't really mean that, so Python makes sure you can cheat despite your
idealistic intentions <wink>.

python-is-an-anti-terrorist-language-ly y'rs  - tim



Thu, 04 Mar 2004 14:23:48 GMT  
 Private variables

Quote:

> > The name mangling of `__bar` names misbehaves if the class name starts
> > with a single underscore. To be able to use `__bar` names safely one
> > has to avoid `_Foo` class names.

> > This is the only example of accidental feature interaction in Python
> > that I'm aware of.

> It's not an accident:  the compiler goes out of its way to remove leading
> underscores from class names while mangling, and this behavior is documented
> in section 5.2.1 (Identifiers -- Private name mangling) of the Ref Man.

When was this documentation added? I don't remember reading that (back
in 1.5.x times; of course, my brain might just have chosen to
selectively ignore it).

Feature or bug, it still is an example of feature interaction waiting
to spring surprises on you.

Quote:
> Suppose it didn't do this.  Then the mangled name in _A would be __A_beep,
> and in A would (still be) _A_beep.  How then in A would you be able to
> access _A's version of beep?  If you typed __A_beep within the scope of A,
> it would get mangled to _A__A_beep:  the point of the rule is so that a
> mangled name never ever "looks like" a private name, so that in turn you can
> always do the mangling by hand (when needed) and not have the compiler
> interfere.

I understand the difficulty. I still think it would have been better
to just use a different (and documented) mangling scheme for class
names starting with a single underscore (like ___A_beep <shudder>).

Quote:
> You could protest that if you *wanted* to access _A's beep from within A you
> never would have made it a private name to begin with -- but Guido knows you
> don't really mean that, so Python makes sure you can cheat despite your
> idealistic intentions <wink>.

My use of `__` names isn't motivated by privacy. The `__` names work
well to allow each class in the hierarchy to have its own unique
variables if it chooses so -- that is handy for some design patterns.
That this variables are open for inspection is a bonus, IMHO.

My consequence is to never use `_Foo` class names. Too bad, that that
means that some classes might be imported by `from X import *` when
I'd rather they wouldn't.

Some-features-are-warts-even-if-documented-ly y'rs
Christian

--

Glasauergasse 32                                       Tel: +43 1 876 62 36
A-1130 Vienna, Austria                                 Fax: +43 1 877 66 92



Thu, 04 Mar 2004 15:44:59 GMT  
 Private variables
[Tim, on Ref Man section 5.2.1 (Identifiers -- Private name mangling)]


Quote:
> When was this documentation added?

You can answer this as easily as I can -- it requires digging into the CVS
history of ref5.tex (quickest is to do a CVS Annotate on SourceForge, using
the ViewCVS web interface).

Quote:
> I don't remember reading that (back in 1.5.x times; of course, my brain
> might just have chosen to selectively ignore it).

Or perhaps you never saw it.  It's in revision 1.17 of ref5.tex, though,
which predates 1.5.2 alpha 1.  Tracing back further than that is difficult,
because the Ref Man was also maintained under Framemaker before then, and
there's no CVS history for that.

Quote:
> Feature or bug, it still is an example of feature interaction waiting
> to spring surprises on you.

Maybe.  This is the first time I heard of anyone having trouble with this,
so I'm afraid I rank it somewhere below dividing by 0 accidentally <wink>.

Quote:
> ...
> I understand the difficulty. I still think it would have been better
> to just use a different (and documented) mangling scheme for class
> names starting with a single underscore (like ___A_beep <shudder>).

Exactly the same difficulty:  that still looks like a private name (which
begin with at least two underscores, not exactly two), so would be subject
to further mangling when written literally.

Quote:
> ...
> My use of `__` names isn't motivated by privacy. The `__` names work
> well to allow each class in the hierarchy to have its own unique
> variables if it chooses so -- that is handy for some design patterns.
> That this variables are open for inspection is a bonus, IMHO.

> My consequence is to never use `_Foo` class names. Too bad, that that
> means that some classes might be imported by `from X import *` when
> I'd rather they wouldn't.

You're unable to define a _Foo class and a Foo class in the same module
without accidentally overlapping their namespaces?  And unable to think up
class names that differ in more than just the presence of leading
underscores?  If so, you can use __all__ to limit import-* visibility now
instead.  Or you could name your classes Foo and _Foo_, etc.

Quote:
> Some-features-are-warts-even-if-documented-ly y'rs
> Christian

"mangling"-is-as-its-name-implies-a-simple-gimmick-not-a-foundation-
    for-a-way-of-life-ly y'rs  - tim


Thu, 04 Mar 2004 17:40:17 GMT  
 Private variables

Quote:



>>They serve different purposes -- a single leading underscore is merely
>>advisory, while a private name is also merely advisory <wink> but
>>indicates you're more serious about it.  Semantically, the single
>>leading underscore means nothing, so is purely convention.

> That's *almost* true.  The convention comes from the fact that in a
> slightly different context, a single leading underscore *does* have
> meaning: module attributes with a single leading underscore do not get
> imported with "from foo import *".  (Well, this was true until the
> __all__ attribute got created, but let's not quibble.)

Another marginal but interesting case is with the Bastion module.  By
default, Bastion exposes the attributes of the object it's wrapping if and
only if their names do not start with underscores.  While you can
explicitly program a different filter, of course, still this default
behavior would lead me to say of the leading-underscore-in-name that it
"means nothing... is purely convention" is somewhat of an underbid.

Alex



Thu, 04 Mar 2004 22:34:06 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. PRIVATE variables (was parameters)

2. Lots of Public and Private variables - no penalties on modern PC.

3. Private variables can be changed outsid e?

4. Private variables can be changed outside?

5. private variables

6. private variables (again)

7. private variable

8. cant see PRIVATE variable in MODULE SUBROUTINE when debugging with IFC/IDB v7.1

9. Accessing private variable as pointer

10. Private variables in Visual Studio

11. Private variables

12. mixed PUBLIC and PRIVATE variables in NAMELIST (Compaq compilers)

 

 
Powered by phpBB® Forum Software