2013-03-18 3 views
1

У меня есть ниже кодошибки в питоне приват-attribute_class

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 

в этом коде является владельцем счета частного атрибутом
и питона мы не можем напрямую редактировать или распечатать.
если мы попытаемся ниже код, питон релиз ошибка

print myaccount.__AccountHolder 

но мои вопросы
1-почему питон не отпускают ошибку в ниже код

myaccount.__AccountHolder="ali" 

2-я печатаю MyAccount .__ владельца счета в end_line, но python не выдает ошибку
и измените значение myaccount .__ AccountHolder to 'ali'

+0

Измените его на 'ali', а затем наберите' Display_AccountHolder() '. – Blender

+0

Display_AccountHolder() работает хорошо, но мой вопрос еще один –

+0

Ну, что же выводит 'Display_AccountHolder()' print out? – Blender

ответ

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: при именовании атрибут класса, вызывает имя mangling (внутри класса FooBar, __boo становится FooBar _boo; см. ниже).

1

Это одна из многих причин, я считаю, что это способ больше проблем, чем это стоит использовать __names в качестве «частных переменных». Предполагаемый вариант использования __names - это больше, чтобы позволить классам в иерархии использовать имена nice (ish), не беспокоясь о том, какие имена используются другими классами в иерархии, а не создавать «частные» атрибуты.

Для «частных» атрибутов просто используйте одиночные подчеркивания (например, _name). Это документирует ваше намерение, что определенные имена являются частными сведениями о реализации, а другие являются частью открытого интерфейса класса. Это не предотвращает, кто использует «личное» имя, но не делает __names, потому что манипуляция очень проста в обратном проектировании. Все эти методы делают это, чтобы кто-либо из случайно использовал имя, которое вы намеревались быть приватным; они могут делать изворотливые вещи, но они должны знать, что они это делают. Это все, что вы можете получить на Python; потому что все динамично, любой может в любой момент сделать что-либо в любом случае.

Так что главное различие между __name и _name для ваших частных внутренних имен является то, что __name станет главным пита, когда вы начинаете хотеть использовать getattr или hasattr (даже в пределах соответствующего класса), динамически присоединять методы, или подкласс что делает хочет поделиться «частным» именем. A _name с одним подчеркиванием не имеет проблем ни в одной из этих областей, так же эффективен при документировании вашего намерения и столь же эффективен (т. Е. Почти полностью неэффективен) в предотвращении использования частных имен вне определения класса.