Форум сайта python.su
Задача: в некотором клиентском классе SomeClass описать свойство myName (имя экземпляра), разместив атрибут value в классе-дескрипторе Name. Предполагается, что каждый экземпляр класса SomeClass имеет своё собственное имя.
Пишу код (Python 3.6.0):
class Name: # name descriptor def __init__(self): self.value = 'default name' def __get__(self, instance, owner): return self.value def __set__(self, instance, value): self.value = value def __delete__(self, instance): raise AttributeError('from Name.__delete__') class SomeClass: myName = Name() #--------------------------------------------------------------------------------- if __name__ == '__main__': a = SomeClass() b = SomeClass() print(a.myName) print(b.myName) a.myName = 'my name is A' print(a.myName) print(b.myName) b.myName = 'my name is B' print(a.myName) print(b.myName) del a.myName
==================== RESTART: Dweb.py/attrs/testdesc.py ==================== default name default name my name is A my name is A my name is B my name is B Traceback (most recent call last): File "D:/web.py/attrs/testdesc.py", line 36, in <module> del a.myName File "D:/web.py/attrs/testdesc.py", line 13, in __delete__ raise AttributeError('from Name.__delete__') AttributeError: from Name.__delete__ >>>
Отредактировано alexgreg (Май 15, 2017 07:15:45)
Офлайн
class SomeClass: def __init__(self): self.myName = Name()
def __repr__(self): return self.value
Отредактировано krok64 (Май 15, 2017 08:28:30)
Офлайн
Разве свойства в __init__ описываются?
Внёс предложенные изменения:
class Name: # name descriptor def __init__(self): self.value = 'default name' def __get__(self, instance, owner): return self.value def __set__(self, instance, value): self.value = value def __delete__(self, instance): raise AttributeError('from Name.__delete__') class SomeClass: def __init__(self): self.myName = Name() #--------------------------------------------------------------------------------- if __name__ == '__main__': a = SomeClass() b = SomeClass() print(a.myName) print(b.myName) a.myName = 'my name is A' print(a.myName) print(b.myName) b.myName = 'my name is B' print(a.myName) print(b.myName) print(a.__dict__) print(b.__dict__) #del a.myName
==================== RESTART: D:\web.py\attrs\testdesc.py ==================== <__main__.Name object at 0x02EBD2D0> <__main__.Name object at 0x03128F70> my name is A <__main__.Name object at 0x03128F70> my name is A my name is B {'myName': 'my name is A'} {'myName': 'my name is B'} >>>
Офлайн
alexgregВ __init__ свойства инициализируются сразу после создания объекта. Для вывода имени по умолчанию посмотри дополнение ко второму сообщению.
Разве свойства в __init__ описываются? Внёс предложенные изменения:
Офлайн
1) в __init__ инициализируются атрибуты экземпляра класса, если self используется, разве не так?
2) если я опишу метод SomeClient.__repr__, при обращении к a.myName какой метод отработает SomeClient.__repr__ или Name.__get__?
Офлайн
alexgregЭто так не работает. Дескриптор это атрибут класса а не инстанса. Вариант топикстартера был правильный, и работал он правильно(с точки зрения пайтона конечно, а не топикстартера).. так и должно быть.
class SomeClass:
def __init__(self):
self.myName = Name()
[code python][/code]
Отредактировано PEHDOM (Май 15, 2017 10:30:59)
Офлайн
где ошибка в первом варианте? предполагается, что каждый экземпляр класса SomeClass должен иметь своё имя, которое хранится в экземпляре соответствующего дескриптора (поле self.value класса Name)
Отредактировано alexgreg (Май 15, 2017 10:31:55)
Офлайн
alexgreg
Для Вашего случая лучше использовать property.
Ошибка в том, что Вы делаете атрибут класса и изменив его через один из экземпляров удивляетесь почему он поменялся у других
Простой пример для понимания
# class A: n = {} # a = A() b = A() a.n["a"] = 12 print(b.n) # {'a': 12}
Отредактировано 4kpt_V (Май 15, 2017 11:00:06)
Офлайн
alexgregвопрос, вам это надо для чего? если для продакшена, то советую использовать чтонить другое(выше советуют property например ), а не дескрипторы, если это задания от преподавателя и нужно использовать именно дексриптеры то есть один нетрадиционный способ(тоесть через жопу) чтобы дескриптор храних значения каждого инстанса.
где ошибка в первом варианте?
[code python][/code]
Офлайн
4kpt_V
alexgreg
Для Вашего случая лучше использовать property.
Офлайн