Can someone explain why was I able to set a private variable without using the setter method?

Can someone explain why was I able to set a private variable without using the setter method?

 
    
     
    
    Yes, you can.
Python doesn't really have private members. However, it does some tricky naming things to try and accomplish as such.
When you do have a __member name, to access it outside, you would use _<ClassName>__<member_name>
[ttucker@zim stackoverflow]$ cat private.py 
class MyClass:
    def __init__(self):
        self.__private = "initial"
    def show(self):
        print(self.__private)
private = MyClass()
private.show()              # -> "initial"
# Does not actually set the private member,
# but creates a public member with the same name 
private.__private = "new"
private.show()              # -> "initial"
print(private.__private)    # -> "new"
# This actually changes the "private" member.
private._MyClass__private = "new"
private.show()              # -> "new"
[ttucker@zim stackoverflow]$ python private.py 
initial
initial
new
new
 
    
    Thanks for @Tomerikoo's answer. I'd like to add something about this.
The key point is that python DOES NOT really have private attributes. Basically, python only changes private attributes' names as format below:
_className__privateAttributeName
So for code in the question, attribute company is just another new attribute. To verify this, we can use dir(obj2) to see the details.
>>> dir(obj2)
(Pdb) dir(obj2)
['_Employee__company', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__
', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__n
e__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook_
_', '__weakref__', 'company', 'get_company', 'name', 'set_company']
(Pdb)
As we can see company and _Employee__company are just two different attributes.
