6
class Car(object):
    def __init__(self, color, engine, oil):
        self.color = color
        self.__engine = engine
        self.__oil = oil

a = Car('black', 'a cool engine', 'some cool oil')

We assume that __engine and __oil variables are private which means I cannot access them through a call like a.__engine. However, I can use __dict__ variable to access and even change those variables.

# Accessing
a.__dict__
{'_Car__engine': 'a cool engine', 'color': 'black', '_Car__oil': 'some cool oil'}

# Changing
a.__dict__['_Car__engine'] = "yet another cool engine"
a.__dict__
{'_Car__engine': 'yet another cool engine', 'color': 'black', '_Car__oil': 'some cool oil'}

The problem is simple. I want private variables to be accessed and changed only inside the class.

Eray Erdin
  • 2,633
  • 1
  • 32
  • 66

2 Answers2

3

The problem is simple. I want private variables to be accessed and changed only inside the class.

So, don't write code outside the class that accesses variables starting with __. Use pylint or the like to catch style mistakes like that.

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • This is not meant to be rude. However, it seems this answer would be nice if you wrote code only for your own personal enjoyment, and never had to hand it on to someone else to maintain it. Any time you're in a collaborative coding environment (any post-secondary education and/or work experience), the code will be used by many. Someone down the line will want to use an easy way to change your `__you_really_should_not_touch_this` variable. They may have a good reason for doing so, but it's possible you set up your code such that their "easy way" is going to break things. Also - black hat. – bballdave025 Aug 20 '19 at 04:14
  • By the way, you're absolutely right about using good programming practices. I especially appreciate that you pointed to a specific tool - `pylint`. – bballdave025 Aug 20 '19 at 06:22
  • 1
    @bballdave025 Access specifiers are not a security feature. In a professional environment you have code review, and the team can decide when they really want to touch what was private. The advantage of not using some obfuscation technique is that third party users don't need to modify upstream code. – Marcin Aug 20 '19 at 12:43
2

What you are trying to do is not possible in Python.

“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python.

https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references

Spc_555
  • 4,081
  • 2
  • 27
  • 34
  • 1
    Technically, that's not really true. You can fake private variables. It's just not really worth it. – Marcin Jan 25 '15 at 16:55
  • 1
    @Marcin I can't think of any way to make a variable in Python technically inaccessible to outside code and have never heard that it is possible. If you do know how to do it, please share. – Spc_555 Jan 25 '15 at 18:34
  • 1
    Mutable default parameter on a method. You can use the method as the mutator and accessor for that container you store in such a default parameter. There's no way to access the underlying datastructure. – Marcin Jan 25 '15 at 19:46
  • @Marcin nope, you can access it (read/modify) using `inspect.getargspec` – Spc_555 Jan 25 '15 at 20:20
  • 1
    Right, and you can access private variables in C++ and Java using pointers and reflection respectively. – Marcin Jan 25 '15 at 20:52