1

I am playing around with private and protected variables in Python. I have created this simple class.

class Simple:
    def __init__(self,foo):
        self.__foo = foo

    def print_foo(self):
        print(self.__foo)

From what I have read, by using the prefix __ I am marking the variable as private. In fact if I try to access it, it will not work:

>> test = Simple(3)
>> print(test.__foo)

AttributeError: 'Simple' object has no attribute '__foo'

However, it lets me "try" to change the value of the variable form outside the class. The value doesn't really change, but it doesn't raise an error

>> test.__foo = 2
>> test.print_foo()
>> print(test.__foo)

3
2

This behavior seems a bit dangerous to me. Am I doing something wrong? Is there a way to raise an error if I try to change the value of a private variable?

jrglez
  • 238
  • 1
  • 10
  • 2
    Python doesn't have "private" variables. You're just assigning a property to an object, period. – deceze Dec 09 '19 at 10:20
  • There is no such thing as 'private variable' in Python. You can indicate to other programmers that the variable is intended for internal/private use by adding underscore. For more information, take a look at this: https://stackoverflow.com/questions/1301346/what-is-the-meaning-of-a-single-and-a-double-underscore-before-an-object-name – Wasi Dec 09 '19 at 10:26
  • 1
    @MisterMiyagi It kind of does, thank you. It's quite weird coming from other languages. I don't see the advantage in not having private variables, but I will have to live with that. – jrglez Dec 09 '19 at 10:28
  • @jrglez If you think about it, most other languages don't have truly "private" variables either. There's usually some sort of bending over backwards you can do to access "private" variables with some form of introspection nonetheless. So "private" or "protected" really just boils down to a flag to programmers *how a variable is intended to be used.* A naming convention like underscores really is entirely sufficient for this purpose. – deceze Dec 09 '19 at 10:37
  • rather then writing i think this article explains it very well : https://dbader.org/blog/meaning-of-underscores-in-python your question comes under the concept of name mangling. – VikasKM Dec 09 '19 at 10:28
  • 1
    @jrglez There isn't any advantage, but then there really isn't any disadvantage either. You can communicate *to other people* which things are `_protected` and `__private``. *Enforcing* it isn't really meaningful in a language such as Python, since class definitions can be changed. Keep in mind that Python isn't compiled -- runtime access control would be very costly. – MisterMiyagi Dec 09 '19 at 10:42
  • Here, when you are creating the object `test` the value `3` will be assigned to an object `test._Simple__foo` instead of `test.__foo`. You can verify this by using the `dis` module i.e. `dis(test)`. So, when you are assigning value to `test.__foo` It creates a new variable for the `test` object which you can access by writing `test.__foo`. But, this doesn't prevent you from modifying the original 'private' variable. To modify that one you can use: `test._Simple__foo = 10` This way the output of print_foo method will be 10 instead of 3! `print(test.print_foo())` – Wasi Dec 09 '19 at 10:45

0 Answers0