Найти - Пользователи
Полная версия: Пример из Лутца
Начало » Python для новичков » Пример из Лутца
1
Niccolum
Добрый день.
Почему следующий код:
 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 # Не вызывает зацикливание:
зацикливание всё таки вызывается. Почему?
Niccolum
И почему в похоже коде с заменой __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? (прикреплено)
terabayt
 #  . . .
def __init__(self, name): # Вызывается при обращении Person()
    self.__dict__['_name'] = name
    self._name = name # Вызовет __setattr__!
#  . . .
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB