Уведомления

Группа в Telegram: @pythonsu

#1 Июль 28, 2016 14:04:32

Niccolum
Зарегистрирован: 2016-04-26
Сообщения: 23
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример из Лутца

Добрый день.
Почему следующий код:

 class Person:
 def __init__(self, name): # Вызывается при обращении Person()
  self._name = name # Вызовет __setattr__!
 def __getattr__(self, attr): # Вызывается операцией obj.undefined
  if attr == 'name': # Для отсутствующего атрибута с именем name
   print('fetch...')
   return self._name # Не вызывает зацикливание:
 # существующий атрибут
  else: # Обращение к другим несуществующим
   raise AttributeError(attr) # атрибутам вызывает ошибку
 def __setattr__(self, attr, value): # Вызывается операцией obj.any = value
  if attr == 'name':
   print('change...')
   attr = '_name' # Внутреннее имя атрибута
   self.__dict__[attr] = value # Предотвратить зацикливание
 def __delattr__(self, attr): # Вызывается операцией del obj.any
  if attr == 'name':
   print('remove...')
   attr = '_name' # Предотвратить зацикливание,
   del self.__dict__[attr] # но менее обычным способом
   
if __name__ == '__main__':
    bob = Person('Bob Smith') # Объект bob обладает управляемым атрибутом
    print(bob.name) # Вызовет __getattr__
    bob.name = 'Robert Smith' # Вызовет __setattr__
    print(bob.name)
    del bob.name # Вызовет __delattr__
    print('-'*20)
    sue = Person('Sue Jones') # Объект sue также наследует свойство
    print(sue.name)
    
Вызывает следующую ошибку:
(прикреплена)
Я так понимаю в строке:
 return self._name # Не вызывает зацикливание:
зацикливание всё таки вызывается. Почему?

Прикреплённый файлы:
attachment logo small.png (23,7 KБ)

Офлайн

#2 Июль 28, 2016 14:10:37

Niccolum
Зарегистрирован: 2016-04-26
Сообщения: 23
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример из Лутца

И почему в похоже коде с заменой __getattr__ на __getattribute__:

 class Person:
 def __init__(self, name): # Вызывается при обращении Person()
  self._name = name # Вызовет __setattr__!
 def __getattribute__(self, attr): # Вызывается операцией [obj.any]
  if attr == 'name': # Перехватывает обращения к любым именам
   print('fetch...')
   attr = '_name' # Отображает на внутреннее имя
   return object.__getattribute__(self, attr) # Предотвратить зацикливание
 def __setattr__(self, attr, value): # Вызывается операцией obj.any = value
  if attr == 'name':
   print('change...')
   attr = '_name' # Внутреннее имя атрибута
   self.__dict__[attr] = value # Предотвратить зацикливание
 def __delattr__(self, attr): # Вызывается операцией del obj.any
  if attr == 'name':
   print('remove...')
   attr = '_name' # Предотвратить зацикливание,
   del self.__dict__[attr] # но менее обычным способом
   
if __name__ == '__main__':
    bob = Person('Bob Smith') # Объект bob обладает управляемым атрибутом
    print(bob.name) # Вызовет __getattr__
    bob.name = 'Robert Smith' # Вызовет __setattr__
    print(bob.name)
    del bob.name # Вызовет __delattr__
    print('-'*20)
    sue = Person('Sue Jones') # Объект sue также наследует свойство
    print(sue.name)
При запуске выводит сообщение, что _name не существует в классе Person? (прикреплено)

Прикреплённый файлы:
attachment logo small.png (25,8 KБ)

Офлайн

#3 Авг. 6, 2016 00:02:16

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Пример из Лутца

 #  . . .
def __init__(self, name): # Вызывается при обращении Person()
    self.__dict__['_name'] = name
    self._name = name # Вызовет __setattr__!
#  . . .



————————————————
-*- Simple is better than complex -*-

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version