"Private" Member Variables

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Scott Brady Drummonds

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



  • Matteo Dell'Amico

    #2
    Re: "Private&q uot; Member Variables

    Scott Brady Drummonds wrote:
    [color=blue]
    > 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?[/color]

    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(objec t):
    def __init__(self, b, h):
    self.b, self.h = b, h
    def get_area(self):
    return self.b * self.h
    area = property(get_ar ea)

    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

    Comment

    • Steve Menard

      #3
      Re: "Private&q uot; Member Variables

      Scott Brady Drummonds wrote:[color=blue]
      > 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
      >[/color]

      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

      Comment

      • Heather Coppersmith

        #4
        Re: "Private&q uot; Member Variables

        On Fri, 28 May 2004 09:56:43 -0700,
        "Scott Brady Drummonds" <scott.b.drummo nds.nospam@inte l.com> wrote:

        [ information hiding? ]
        [color=blue]
        > ... Why not just allow direct reading and writing of the member
        > variable? Is there something here I'm missing?[/color]

        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.
        [color=blue]
        > 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?[/color]

        Just document your intentions, and stick to your documentation.

        Regards,
        Heather

        --
        Heather Coppersmith
        That's not right; that's not even wrong. -- Wolfgang Pauli

        Comment

        • Dave Brueck

          #5
          Re: &quot;Private&q uot; Member Variables

          Scott wrote:[color=blue]
          > 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 some
          good practices?" as opposed to "This is different, it must be broken!".
          [color=blue]
          > 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?[/color]

          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.


          Comment

          • Marcus von Appen

            #6
            Re: &quot;Private&q uot; Member Variables

            "Scott Brady Drummonds" <scott.b.drummo nds.nospam@inte l.com> writes:

            [...][color=blue]
            > class C:
            > ...
            > def value(self):
            > return self.__value
            > ...[/color]

            [color=blue]
            > 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?[/color]

            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' ;-).
            [color=blue]
            > 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?[/color]

            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!

            Comment

            • David Bolen

              #7
              Re: &quot;Private&q uot; Member Variables

              Marcus von Appen <mva@sysfault.o rg> writes:
              [color=blue]
              > 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.[/color]

              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

              Comment

              • Isaac To

                #8
                Re: &quot;Private&q uot; Member Variables

                >>>>> "Scott" == Scott Brady Drummonds <scott.b.drummo nds.nospam@inte l.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:
                [color=blue][color=green][color=darkred]
                >>> class C:[/color][/color][/color]
                .... def value(self):
                .... return self.__value
                .... def setvalue(self, val):
                .... self.__value = val
                ....[color=blue][color=green][color=darkred]
                >>> c = C()
                >>> c.setvalue(5)
                >>> c.value()[/color][/color][/color]
                5[color=blue][color=green][color=darkred]
                >>> c.__value[/color][/color][/color]
                Traceback (most recent call last):
                File "<stdin>", line 1, in ?
                AttributeError: C instance has no attribute '__value'[color=blue][color=green][color=darkred]
                >>> dir(c)[/color][/color][/color]
                ['_C__value', '__doc__', '__module__', 'setvalue', 'value'][color=blue][color=green][color=darkred]
                >>> c._C__value[/color][/color][/color]
                5[color=blue][color=green][color=darkred]
                >>> c._C__value = 10
                >>> c.value()[/color][/color][/color]
                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.

                Comment

                • Alan Gauld

                  #9
                  Re: &quot;Private&q uot; Member Variables

                  On Fri, 28 May 2004 09:56:43 -0700, "Scott Brady Drummonds"
                  <scott.b.drummo nds.nospam@inte l.com> wrote:[color=blue]
                  > 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
                  > ...[/color]

                  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.
                  [color=blue]
                  > 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?[/color]

                  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.
                  [color=blue]
                  > What are your thoughts? How much privacy should I build into my code?[/color]

                  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

                  Comment

                  • Hung Jung Lu

                    #10
                    Re: &quot;Private&q uot; Member Variables

                    Alan Gauld <alan.gauld@bti nternet.com> wrote:[color=blue]
                    >
                    > There is very rarely any good reason to provide getXXX/setXXX
                    > type accessor functions, even in C++
                    >[/color]

                    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_pric e = 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.
                    [color=blue]
                    > Exposing your data via accessor functions is still exposing it
                    > (albeit with control over read/write access).[/color]

                    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

                    Comment

                    • F. GEIGER

                      #11
                      Re: &quot;Private&q uot; Member Variables


                      "Scott Brady Drummonds" <scott.b.drummo nds.nospam@inte l.com> schrieb im
                      Newsbeitrag news:c97r0b$jqq $1@news01.intel .com...[color=blue]
                      > 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[/color]
                      group.[color=blue]
                      >
                      > 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[/color]
                      C++[color=blue]
                      > (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?[/color]

                      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.__whatToSa y

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

                      and NOT
                      myObj = MyClass()
                      s = myObj._whatToSa y
                      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
                      [color=blue]
                      >
                      > 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.
                      >
                      >
                      >[/color]


                      Comment

                      Working...