1

我有以下代码

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-我在 end_line 中打印 myaccount.__AccountHolder 但 python 未释放错误
并将 myaccount.__AccountHolder 的值更改为 'ali'

4

2 回答 2

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:命名类属性时,调用名称修改(在类 FooBar 中,__boo 变为FooBar _boo;见下文)。

于 2013-03-18T21:34:14.830 回答
1

这是我认为它比用作“私有变量”更麻烦的众多原因之一。__names的预期用例__names更多的是允许层次结构中的类使用漂亮的(ish)名称,而不必过多担心层次结构中的其他类使用什么名称,而不是创建“私有”属性。

对于“私有”属性,只需使用单个前导下划线(如_name)。这记录了您的意图,即某些名称是私有实现细节,而其他名称是类的公共接口的一部分。它不会阻止任何人使用“私人”名称,但也不会阻止,__names因为修改很容易进行逆向工程。所有这些技术都可以防止任何人意外使用您打算保密的名称;他们可以做一些狡猾的事情,但他们必须知道他们正在这样做。这就是你在 Python 中所能得到的一切;因为一切都是动态的,任何人都可以随时做任何事情。

因此,您的私有内部名称之间的主要区别在于__name,当您开始想要使用或(甚至在正确的类中)动态附加方法或有一个确实想要共享“私有”的子类时,它将成为一个主要的 PITA姓名。带有单个下划线的 A在任何这些领域都没有问题,在记录您的意图方面同样有效,并且在防止在类定义之外使用私有名称方面同样有效(即几乎完全无效)。_name__namegetattrhasattr_name

于 2013-03-18T21:57:16.307 回答