python private-attribute_class中的一个错误

时间:2013-03-18 21:28:07

标签: python python-2.7

我有以下代码

class AccountBannk:
    def __init__(self,balance,holder):
        self.__AccountHolder=holder
    def Display_AccountHolder(self):
        print "account holder is" , self.__AccountHolder
myaccount=AccountBannk(100000,"mehdiebagvand")
#print myaccount.__AccountHolder #is a error
myaccount.__AccountHolder="ali"
print myaccount.__AccountHolder      #print ali

在此代码中AccountHolder是私有属性
在python中我们无法直接编辑或打印它 如果我们尝试下面的代码,python发布错误

print myaccount.__AccountHolder

但我的问题是 1 - 为什么python不会在下面的代码中发布错误

myaccount.__AccountHolder="ali"

2-I在end_line中打印myaccount .__ AccountHolder但是python没有释放错误
并将myaccount .__ AccountHolder的值更改为'ali'

2 个答案:

答案 0 :(得分:3)

这不是错误。当你在你的类中定义你的第一个__AccountHolder时,Python会破坏变量的名称(很难猜测,但不是真正的私有,请参阅PEP-8)。当你附加第二个__AccountHolder时,你正在创建一个新的变量(带有一个新的变形名称)。试试看:

print myaccount.__AccountHolder
print myaccount.Display_AccountHolder()

或添加

print dir(myaccount)

在你做第二次任务之前和之后:

>>> myaccount=AccountBannk(100000,"mehdiebagvand")
>>> dir(myaccount)
    ['Display_AccountHolder', '_AccountBannk__AccountHolder', '__doc__', '__init__', '__module__']
>>> myaccount.__AccountHolder="ali"
>>> dir(myaccount)
    ['Display_AccountHolder', '_AccountBannk__AccountHolder', '__AccountHolder', '__doc__', '__init__', '__module__']

至于名称修改,这里来自文档:

  

__ double_leading_underscore:在命名一个class属性时,调用name mangling(在类FooBar中,__ boo变成 FooBar _boo;参见   下文)。

答案 1 :(得分:1)

这是我认为使用__names作为“私有变量”比使用{em>方式更麻烦的众多原因之一。 __names的预期用例更多是允许层次结构中的类使用nice(ish)名称,而不必担心层次结构中其他类正在使用哪些名称,而不是创建“私有”属性。

对于“私有”属性,只需使用单个前导下划线(如_name)。这表明您的意图是某些名称是私有实现细节,而其他名称是该类的公共接口的一部分。它不会阻止任何使用“私有”名称的人,但__names也不会,因为修改非常容易进行逆向工程。所有这些技巧都可以防止任何人意外使用你想要私密的名字;他们可以做狡猾的事情,但他们必须知道他们正在做这件事。这是Python中可以获得的全部内容;因为一切都是动态的,任何人都可以随时做任何事情。

因此,对于您的私人内部名称,__name_name之间的主要区别在于,只要您开始想要使用__name或{{getattrhasattr就会成为主要的PITA 1}}(即使在正确的类中),动态附加方法,或者具有 想要共享“私有”名称的子类。具有单个下划线的_name在任何这些区域都没有问题,在记录您的意图方面同样有效,并且在防止在类定义之外使用私有名称方面同样有效(即几乎完全无效)。