Tags: burnt, develop, experience, learning, medium-sized, member, mind, myprevious, private, programming, project, python, variables

"Private" Member Variables

On Programmer » Python

21,162 words with 9 Comments; publish: Tue, 29 Apr 2008 18:02:00 GMT; (20077.88, « »)

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.

All Comments

Leave a comment...

  • 9 Comments
    • 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

      #1; Tue, 29 Apr 2008 18:04:00 GMT
    • 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

      #2; Tue, 29 Apr 2008 18:05:00 GMT
    • On Fri, 28 May 2004 09:56:43 -0700,

      "Scott Brady Drummonds" <scott.b.drummonds.nospam.python.todaysummary.com.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

      #3; Tue, 29 Apr 2008 18:06:00 GMT
    • 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.[/color

      ]

      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 so

      me

      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 classe

      s

      are closer to C structures (they are mostly dumb data containers), so it mak

      es

      "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 wit

      h

      class internals that could break things.

      -Dave

      P.S. The only time I use underscore prefixes is for the direct-access classe

      s.

      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.

      #4; Tue, 29 Apr 2008 18:07:00 GMT
    • "Scott Brady Drummonds" <scott.b.drummonds.nospam.python.todaysummary.com.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!

      #5; Tue, 29 Apr 2008 18:08:00 GMT
    • Marcus von Appen <mva.python.todaysummary.com.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

      #6; Tue, 29 Apr 2008 18:09:00 GMT
    • >>>>> "Scott" == Scott Brady Drummonds <scott.b.drummonds.nospam.python.todaysummary.com.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:

      ... def value(self):

      ... return self.__value

      ... def setvalue(self, val):

      ... self.__value = val

      ...

      5

      Traceback (most recent call last):

      File "<stdin>", line 1, in ?

      AttributeError: C instance has no attribute '__value'

      ['_C__value', '__doc__', '__module__', 'setvalue', 'value']

      5

      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.

      #7; Tue, 29 Apr 2008 18:10:00 GMT
    • On Fri, 28 May 2004 09:56:43 -0700, "Scott Brady Drummonds"

      <scott.b.drummonds.nospam.python.todaysummary.com.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

      #8; Tue, 29 Apr 2008 18:11:00 GMT
    • Alan Gauld <alan.gauld.python.todaysummary.com.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

      #9; Tue, 29 Apr 2008 18:12:00 GMT