在python3.6中,为什么对象中的私有属性可以直接调用?是我代码哪里错了吗?

图片说明

图片说明

python没限制访问权限

instanceObject = someclass()
instanceObject.method()
python会自动将实例对象调用实例方法映射成someclass.method(instanceObject)即类"调用"实例方法处理实例对象,这就容易理解为何在定义实例方法时的第一个参数为何是self(the implied instance有人翻译成隐式实例对象),或者说self为何在运行时就是调用方法函数的实例对象本身的说法了。

i1.w() => C1.w(i1) self被赋值i1
i1是C1类的实例对象
w是C1的实例方法函数

由此推得 类.方法函数(实例对象) 等价于 实例对象.方法函数() 调用python脚本均支持
——————————————————————————————————
class Ca:
def pr(self):
print "a--->"
ia = Ca()
ia.pr()
Ca.pr(ia)
——————————————————————————————————
运行结果
a--->
a--->

总结
instance.method(args...) 等价于
class.method(instance, args...)

你的代码:
dog1.__age = -10
这句话会设置一个实例属性: age 而这个属性跟类中的私有属性 self.age 并不是同一个,它们都有独立的命名空间。

如果你想 age 不能被设置为实例属性,则需要使用 __slots 变量:
class dog():
slots = ('__age',) # 用tuple定义允许绑定的属性名称

具体参考:
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143186739713011a09b63dcbd42cc87f907a778b3ac73000

python中没有像java那样的protect和private变量保护,python中所谓的私有变量都能通过类名__属性名访问.

你的疑惑应该是这个__age是私有属性, 不能被直接调用, 是吧.

但是在python中, 并没有真正意义上的私有属性, 也就是说你在属性名前面加上__的作用并不是让这个属性变成了你理解的私有属性, 而仅仅是让别人知道我想要把这个属性设置为私有属性, 及我不希望使用者来调用这个属性. 就相当于是一个注释一样. 所以当你调用这个私有属性的时候还是可以调用的, 因为python没有真正意义上的私有属性.

没有 dog1.__age = -10这一行的话你肯定访问不到

要注意这里dog类里面的__age已经变成了_dog__age(这是python中的name mangling 技术),你这样dong1.__age=-10,实际上是建立了一个新的属性__age,和类里面的实际不是同一个。上面那个回答很好的补充了此内容,就是一种伪私有。