473,320 Members | 1,978 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

"Private" Member Variables

Hi, everyone,

I'm still learning Python as I develop a medium-sized project. From my
previous experience with C++, I've burnt into my mind the notion of
information hiding. I'm having trouble understanding to what extent I
should follow this policy in my Python code so I thought I'd ask the group.

I read from a previous post that to attain a private-like status of member
variables, I should prefix the variable name with two underscores ("__").
This does work, but in another post someone asked me if this was really
necessary. Given that the very nature of the language precludes any
compile-time type dependencies I'm wondering if there is any benefit to
naming variables with leading underscores and providing accessor functions
like this:
class C:
...
def value(self):
return self.__value
...

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

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

Thanks,
Scott

--
Remove .nospam from my e-mail address to mail me.

Jul 18 '05 #1
10 3287
Scott Brady Drummonds wrote:
What are your thoughts? How much privacy should I build into my code?
Should I be using variables beginning with "__" and accessors? Or is that
simply not necessary (or normal) in Python code?


The motto here is "we are all consenting adults". If the class users
need to access a variable, then why not make it directly available?

If you later notice that you'd need an accessor method, since the value
of the "variable" has got to be precomputed, then use properties[1]. For
instance:

class Rectangle(object):
def __init__(self, b, h):
self.b, self.h = b, h
def get_area(self):
return self.b * self.h
area = property(get_area)

In this case the property is read-only, but you can also put a setter if
you need it.

[1] You need new-style classes for properties, so make sure you inherit
from object or one of its descendants.

--
Ciao,
Matteo
Jul 18 '05 #2
Scott Brady Drummonds wrote:
Hi, everyone,

I'm still learning Python as I develop a medium-sized project. From my
previous experience with C++, I've burnt into my mind the notion of
information hiding. I'm having trouble understanding to what extent I
should follow this policy in my Python code so I thought I'd ask the group.

I read from a previous post that to attain a private-like status of member
variables, I should prefix the variable name with two underscores ("__").
This does work, but in another post someone asked me if this was really
necessary. Given that the very nature of the language precludes any
compile-time type dependencies I'm wondering if there is any benefit to
naming variables with leading underscores and providing accessor functions
like this:
class C:
...
def value(self):
return self.__value
...

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

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

Thanks,
Scott


I see no problem with exposing the attribute directly, if that attribute
may be freely modified without verification. The main problem with doing
this in C++ and other languages, is that changing to a calculated value
down the road would break existing code.

In python, if an attribute suddenly needs to be validated at assignment
time, of has to be calculated at "get" time, you can make it a property.
Client code won;t see the difference.

However, for the sake of consistency, I would make all get/set accessed
that cannot be direct into properties.

Steve
Jul 18 '05 #3
On Fri, 28 May 2004 09:56:43 -0700,
"Scott Brady Drummonds" <sc**********************@intel.com> wrote:

[ information hiding? ]
... Why not just allow direct reading and writing of the member
variable? Is there something here I'm missing?
Why not indeed? No, there's nothing you're missing. Python takes
a "we're all adults here" philosophy. Collections of trivial
getters/setters are just clutter (and, IMHO, mean that your class
is merely encapsulating data rather than functionality; obviously,
though, there are times when that's the Right Thing).

If there's something worth "hiding," write a wrapper function,
document it, and use it. If there's nothing worth hiding, then
don't write a wrapper function, document the members, and just
access the members directly.

You know your application as well as anyone. You'll know (or
learn from experience) when it's time to present an interface to
larger functionality rather than just let the rest of the code
directly at your objects' members.

At worst, you can convert individual members to properties, and
run arbitrary code to access those properties, but explicit is
better than implicit.
What are your thoughts? How much privacy should I build into my
code? Should I be using variables beginning with "__" and
accessors? Or is that simply not necessary (or normal) in
Python code?


Just document your intentions, and stick to your documentation.

Regards,
Heather

--
Heather Coppersmith
That's not right; that's not even wrong. -- Wolfgang Pauli
Jul 18 '05 #4
Scott wrote:
I'm still learning Python as I develop a medium-sized project. From my
previous experience with C++, I've burnt into my mind the notion of
information hiding. I'm having trouble understanding to what extent I
should follow this policy in my Python code so I thought I'd ask the group.
Holy cow, Scott! Congratulations - many people come to Python from other
languages and are completely unable or unwilling to believe that Python's
approach to information hiding isn't broken. Many of them, upon seeing that it
is more relaxed than C++ even postulate that Python doesn't support
object-oriented programming (which is funny, but annoying).

I'm sure other people will better answer your question, but I just wanted to
say 'thanks' because it's refreshing to hear "This is different, what are some
good practices?" as opposed to "This is different, it must be broken!".
why provide an accessor at all? Why not just allow direct reading and
writing of the member variable? Is there something here I'm missing?

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


IMO the thing that matters most is consistency. For a given class, just make
sure you go all one way or another - all direct access or all accessor
functions. I like the fact that you have the freedom to choose - some classes
are closer to C structures (they are mostly dumb data containers), so it makes
"sense" to access them in that way. Other classes more closely represent the
traditional notion of an object (data + operations on the data), so access
through functions is a cleaner interface and safeguards against fiddling with
class internals that could break things.

-Dave

P.S. The only time I use underscore prefixes is for the direct-access classes.
If I document the class as one in which you should use the accessors instead of
going direct, then I generally don't bother with the underscores.
Jul 18 '05 #5
"Scott Brady Drummonds" <sc**********************@intel.com> writes:

[...]
class C:
...
def value(self):
return self.__value
...
The problems that arise from directly relying on the member variable in C++
(compile-time type dependency, as I said above) don't exist in Python. So
why provide an accessor at all? Why not just allow direct reading and
writing of the member variable? Is there something here I'm missing?
Yes. Imagine a class, which's attributes should only be able to hold a
specific value range, e.g. a triangle, of which the side length should not
exceed 10.
If you would use the class as - let's say a third party developer and this
class does not contain an accessor nor this 'private' indicator (_ or __),
you possibly would not know about that limited value range.

You would simply type in triangle.side = 50.
Now another calculation method using that triangle object could receive
a value overflow, because it cannot calculate with such a 'big' value, but
is limited to 10.

An accessor and private attribute could avoid this:
* You would know, that the author of the class does not want you to modify
the attribute directly.
* The accessor could test the value range at input.
....
etc.pp.

You see: It makes sense for other developers, so they can easily see the
difference between your private attributes, which are not meant to be used
directly and public usable ones.

Another advantage is that your private method and attribute documentations
are not shown using 'pydoc YourClass' ;-).
What are your thoughts? How much privacy should I build into my code?
Should I be using variables beginning with "__" and accessors? Or is that
simply not necessary (or normal) in Python code?


As written above, it can make sense. You have to determine, if it is useful
for you :-).

Regards
Marcus

--
We don't understand the software, and sometimes we don't understand the
hardware, but we can *see* the blinking lights!
Jul 18 '05 #6
Marcus von Appen <mv*@sysfault.org> writes:
Yes. Imagine a class, which's attributes should only be able to hold a
specific value range, e.g. a triangle, of which the side length should not
exceed 10.
If you would use the class as - let's say a third party developer and this
class does not contain an accessor nor this 'private' indicator (_ or __),
you possibly would not know about that limited value range.

You would simply type in triangle.side = 50.
Now another calculation method using that triangle object could receive
a value overflow, because it cannot calculate with such a 'big' value, but
is limited to 10.

An accessor and private attribute could avoid this:
* You would know, that the author of the class does not want you to modify
the attribute directly.
* The accessor could test the value range at input.
...
etc.pp.


Except that Python doesn't make you use accessors to gain this
behavior. If in fact you have such a class, and yet you still want to
be able to permit users to use it in the above manner, simply make the
"side" attribute into a property (which function as accessors but
hidden behind normal attribute access syntax), and you get full
control when someone tries to assign something to do, at which point
you can validate the input all you want.

In terms of knowing that a class enforces such rules, that's something
I would expect documented by the class, regardless of implementation.

And the great thing is you can initially start out with a normal
non-property attribute, and convert it to a property at some point in
the future if you need to, without affecting any existing users of the
code (well, unless their prior use is later considered invalid, but
that would be true if you changed the rules checked by an accessor as
well).

-- David
Jul 18 '05 #7
>>>>> "Scott" == Scott Brady Drummonds <sc**********************@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.
Jul 18 '05 #8
On Fri, 28 May 2004 09:56:43 -0700, "Scott Brady Drummonds"
<sc**********************@intel.com> wrote:
necessary. Given that the very nature of the language precludes any
compile-time type dependencies I'm wondering if there is any benefit to
naming variables with leading underscores and providing accessor functions
like this:
class C:
...
def value(self):
return self.__value
...
There is very rarely any good reason to provide getXXX/setXXX
type accessor functions, even in C++ (JavaBeans are something
of an exception because tools need them). The whole point of
information *hiding* is that external objects can't access your
internal data, they access behaviours. Exposing your data via
accessor functions is still exposing it (albeit with control over
read/write access). But why does another object need your data?
you own it so you should manage it, if something needs doing you
should do it - via a behaviour. Indeed, there is a school of
thought in OOD that says member data is *only* there to support
the published behaviour.

Now you may want behaviour that returns a bit of data (like bank
account balance) but even in that case, conceptually the balance
could be a calculated value. But if you really must display your
internal data to the world the best way is as a property IMHO.
why provide an accessor at all? Why not just allow direct reading and
writing of the member variable? Is there something here I'm missing?
There should be very little need to access the data at all if the
class provides the needed set of ehaviours. If you have an
application where objectts are accessing other objects data then
that's usually a sign that the OO Design is broken somewhere.
What are your thoughts? How much privacy should I build into my code?


If there is tight dependency between two values such that if
somebody external changed one (through not appreciating the
interdependency) it would make the other semantically inaccurate
then its a good idea to hide them to protect yourself. But if we
allow a certain amount of trust in our fellow programmers all
other variables can be left exposed and we rely on them to use
the behaviour published via the methods and not to mess with the
innards.

That's my personal approach at least...

OTOH If you are putting your objects out as a library for general
consumption you may take a more conservative view based on the
idea that the less things users can break the less work for you.

Alan G.
Author of the Learn to Program website
http://www.freenetpages.co.uk/hp/alan.gauld
Jul 18 '05 #9
Alan Gauld <al********@btinternet.com> wrote:

There is very rarely any good reason to provide getXXX/setXXX
type accessor functions, even in C++

Accessor methods are often needed in simple-generic programming in
C++/Java/C#. (With the coming of actual generics in Java/C#,
accessors/properties will be even more common. C++ does get away a
little bit because it has weakly-typed templates.)

There is an asymmetry between data member and function members in
C++/Java/C#. Whereas in Python you have virtual data fields, in
C++/Java/C# you DON'T. You only have virtual functions.

This is a gigantic limitation. In Python, you write a parent class to
access child-class attributes all the time. In fact, you often use
statements like:

if hasattr(self, 'tax'):
self.total_price = self.price + self.tax

in the parent class, where the 'tax' attribute exists only for a
taxable child class.

Similarly, getters/setters are necessary in mix-in classes in Java/C#.
To me, one main reason for getters/setters is the lack of virtual data
fields. You NEED to use accessor methods to emulate virtual data
fields.
Exposing your data via accessor functions is still exposing it
(albeit with control over read/write access).


In C++/Java/C#, very often it's not a matter of choice, but a matter
of need. Without accessor methods, you have no way of writing generic
programs like:

(a) a parent class accessing data fields of a child class
(b) a mix-in class accessing data fields of the main class

(Mix-ins are achieved by containment plus possible delegation, that's
the way how multiple inheritance works in Java/C#).

regards,

Hung Jung
Jul 18 '05 #10

"Scott Brady Drummonds" <sc**********************@intel.com> schrieb im
Newsbeitrag news:c9**********@news01.intel.com...
Hi, everyone,

I'm still learning Python as I develop a medium-sized project. From my
previous experience with C++, I've burnt into my mind the notion of
information hiding. I'm having trouble understanding to what extent I
should follow this policy in my Python code so I thought I'd ask the group.
I read from a previous post that to attain a private-like status of member
variables, I should prefix the variable name with two underscores ("__").
This does work, but in another post someone asked me if this was really
necessary. Given that the very nature of the language precludes any
compile-time type dependencies I'm wondering if there is any benefit to
naming variables with leading underscores and providing accessor functions
like this:
class C:
...
def value(self):
return self.__value
...

The problems that arise from directly relying on the member variable in C++ (compile-time type dependency, as I said above) don't exist in Python. So
why provide an accessor at all? Why not just allow direct reading and
writing of the member variable? Is there something here I'm missing?
Classes should offer services, not data. This holds for any programming
language. If you remember this while designing your software you will stop
to think of variables and their not/privateness.

Most people who speak of information hiding don't get it right. They end up
def'ing private variables and then they write getters and setters to access
them. This is NOT information hiding, it's the opposite (simple data
containers being an exception, of course).

Now, if you know all this it really doen't matter much if you write
self.whatToSay or
self._whatToSay or
self.__whatToSay

because your call should be
myObj = MyClass("Hello")
myObj.sayIt(Printer())

and NOT
myObj = MyClass()
s = myObj._whatToSay
print s

In Python things concerning even the bad example are somewhat better because
you do not know explicitly what type s is of. In C++ most people show all
the world, that they access a string, no matter if they use a getter or not.
Sure, they def'ed the string as private, but the information is not hidden,
by no means: Everyone knows, it's a string!

HTH
Franz GEIGER

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

Thanks,
Scott

--
Remove .nospam from my e-mail address to mail me.

Jul 18 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Steven Bethard | last post by:
Philippe C. Martin wrote: > class Debug_Stderr: > __m_text = '' > __m_log_text = None > __m_dbg = None > __m_refresh_count = 0 <rant> I don't see the benefit in 99.9% of cases for...
4
by: BillyMac | last post by:
Hello I emply a "plug-in" architecture for a .NET Windows service. At OnStart, the service browses for DLL's in in sub-folders and loads them dyanamically using Assembly.LoadFrom() The...
8
by: Etienne Boucher | last post by:
Nested classes are usualy objects made to only live in their parent object instance. In other words... public class Outter { public class Inner { } }
1
by: Edward | last post by:
I have trouble with some of the concepts of OOP, and am struggling currently with Private Shared Functions. I think I understand Private (not available outside the class). I think I understand...
3
by: Jordan Taylor | last post by:
I am confused about protected member functions and objects. Is there any particular advantage of declaring members protected?
1
by: metiu | last post by:
Hi all, maybe it's an old question, but I couldn't find an answer... let's say I have this kind of directory structure for project foo: /foo/includes/mod1.h (exported by mod1)...
4
by: Peter K | last post by:
Hi if I am developing a "class library" which contains some classes which should be exposed to the outside world, and other classes which I really would rather have "private" to my library...
16
by: Joe Strout | last post by:
One thing I miss as I move from REALbasic to Python is the ability to have static storage within a method -- i.e. storage that is persistent between calls, but not visible outside the method. I...
0
by: Luis Zarrabeitia | last post by:
Quoting Joe Strout <joe@strout.net>: I'm sure your credentials are bigger than mine. But he is right. A lot of languages have ditched the "concept" of a static variable on a method (how do you...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.