I found this code:
public="a" # is a public variable
_protected="b" # is a protected variable
__private="c" # is a private variable
Example of how it's used:
class c1:
def __init__(self,a,b,c):
self.public=a
self._protected=b
self.__private=c
v=c1("A","B","C")
print(v.public)
v._protected="Be" # !??? I can access a protected variable
print(v._protected)
print(v.__private) # !??? AttributeError: 'c1' object has no attribute '__private'
Why can I access a variable that was supposed to be a protected variable!?
No, Python does not have access modifiers which outright prevent access. But then again, most languages don't. Even languages which sport protected and private keywords usually have some way through introspection or such to get at the value anyway in ways which "should not be allowed."
Access modifiers are, one way or another, just a hint as to how the property is supposed to be used.
Python's philosophy is to assume that everyone contributing code is a responsible adult, and that a hint in the form of one or two underscores is perfectly enough to prevent "unauthorised access" to a property. If it starts with an underscore, you probably shouldn't mess with it.
Python doesn't have modifiers like private, protected, public. You can emulate their behavior with __getattr__ and __getattribute__, but it's not a Pythonic way to write programs.
Using single underscore _ is a convention, so when you see an attribute or method starting with one underscore, consider that library developer didn't expect it to be part of public API. Also when executing from module import * Python interpreter doesn't import names starting with _, though there're ways to modify this behavior.
Using double underscore __ is not just a convention, it leads to "name-mangling" by interpreter - adding class name in front of attribute, so i.e.:
class Klass():
def __like_private():
print("Hey!")
will make _Klass__like_private.
You won't be able to access __like_private directly as defined, though you still will be able to get to it knowing how names are composed by using _Klass__like_private() in subclasses for example or in module:
Klass.__like_private() will give you an error.
Klass._Klass__like_private() will print Hey!.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With