5

Possible Duplicate:
private members in python

I've got few variables I really want to hide because they do not belong outside my class. Also all such non-documented variables render inheritance useless.

How do you hide such variables you don't want to show outside your object?

To clarify why I need private variables, first one example where inability to hide variables is just an inconvenience, then another that's really a problem:

class MyObject(object):
    def __init__(self, length):
        self.length = length
    def __len__(self):
        return length

item = MyObject(5)
item.length
len(item)

So I've got two ways to access 'length' of the item here. It's only an inconvenience and nothing horrible.

from wares import ImplementationSpecific

class MyThing(object):
    def __init__(self):
        self.__no_access_even_if_useful = ImplementationSpecific()
    def restricted_access(self):
        return self.__no_access_even_if_useful.mutable_value

thing = MyThing()
thing.restricted_access()
thing._MyThing__no_access_even_if_useful.something_useful_for_someone()

So say I want to change the implementation some day.. The chances are it'll break something unless I've really buried the implementation specifics.

I'll take it as anyone could program. That 'anyone' can find an useful thing from my implementation specifics and use it, even if I'd have strongly discouraged of doing so! It'd be much easier to just say: "no, it's not there, try something else."

Community
  • 1
  • 1
Cheery
  • 24,645
  • 16
  • 59
  • 83
  • 1
    You want the variables not to inherit, correct? – Paul Nathan Jul 20 '10 at 22:04
  • 7
    Python doesn't do bondage and domination like some languages do. If you can't stop yourself from using `_method` or `_datum` (see DrDee below) you deserve what you get (or don't get (or break)). – msw Jul 20 '10 at 22:09
  • 2
    You can't avoid inheriting attributes. You can only make it obvious that you're not supposed to mess with them (by using the leading underscore given in the actual answers here.) – Thomas Wouters Jul 20 '10 at 22:09
  • @msw +1 for using "bondage" and "domination" in a comment. – TheJacobTaylor Jul 20 '10 at 22:12
  • An interesting aspect of algebras is that adding rules generates more interesting and useful mathematical systems. /justathought – Paul Nathan Jul 20 '10 at 22:13
  • So I can use double underscores (`__variable`) to apply name mangling. But I want to *really* hide it. Disappear from the users radar. – Cheery Jul 20 '10 at 22:18
  • 1
    @Cheery: maybe you could tell us more about your users, and what sort of "radar" they are using. – Ned Batchelder Jul 20 '10 at 22:32
  • What was the point of removing ChristopheDs answer? – Cheery Jul 20 '10 at 22:43
  • @Cheery: I deleted it myself since user Thomas Wouters convinced me with the arguments against the usage of `__`. – ChristopheD Jul 20 '10 at 22:46
  • @Ned Batchelder: The user is me. Also, my radar was simply `dir(instance)`. Why do I want to hide something from myself? The question is same as asking why do I want closures? I want to hide information so relevant stuff stays uncluttered. – Cheery Jul 20 '10 at 22:47
  • I can't speak for anyone else, but I've deleted an answer or two of my own when I was embarrassingly, wildly wrong (the mere embarrassing I usually leave). @Cheery - I suggest you read Phil Dick's "A Scanner Darkly" – msw Jul 20 '10 at 22:48

2 Answers2

15

Private variables is covered in the Python documentation:

9.6. Private Variables

“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.

Summary: use an underscore before the name.

Community
  • 1
  • 1
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
11

From the Python docs:

“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.

DrDee
  • 3,549
  • 6
  • 30
  • 37