Уведомления

Группа в Telegram: @pythonsu

#1 Март 17, 2011 22:46:18

Actor
От:
Зарегистрирован: 2010-10-10
Сообщения: 39
Репутация: +  0  -
Профиль  

Вопрос по классам (вырезка из книжки)

В одной книге наткнулся на следующий кусок:

В языке Python не считается зазорным получить доступ к некоторому атрибуту (не методу) напрямую, если, конечно, этот атрибут описан в документации как часть интерфейса класса. Такие атрибуты называются свойствами (properties). В других языках программирования принято для доступа к свойствам создавать специальные методы (вместо того чтобы напрямую обращаться к общедоступным членам-данным). В Python достаточно использовать ссылку на атрибут, если свойство ни на что в объекте не влияет (то есть другие объекты могут его произвольно менять). Если же свойство менее тривиально и требует каких-то действий в самом объекте, его можно описать как свойство (пример взят из документации к Python):
class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")

Синтаксически доступ к свойству x будет обычной ссылкой на атрибут:
>>> c = C()
>>> c.x = 1
>>> print c.x
1
>>> del c.x
А на самом деле будут вызываться соответствующие методы: setx(), getx(), delx().
Собственно вопрос, для чего следующая строка?
x = property(getx, setx, delx, "I'm the 'x' property.")



Отредактировано (Март 17, 2011 22:46:46)

Офлайн

#2 Март 18, 2011 01:21:57

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопрос по классам (вырезка из книжки)

Actor
x = property(getx, setx, delx, "I'm the 'x' property.")
функция появилась вместе с новыми классами.
x = property(get, set, del, doc) по сути переопределяет методы __getattr__, __setattr__, __delattr__ но только для конкретно этого атрибута.
то есть при вызове:

c = C()
c.x = 1 #- здесь происходит неявный вызов setx вместо стандартного __setattr__
print c.x # - getx вместо __getattr__
del c.x # - delx вместо __delattr__
Но если использовать любой другой атрибут то будут использоваться стандартные методы.
class C(object):
def getx(self):
print 'getx works...'
return self.__x
def setx(self, value):
print 'setx works...'
self.__x = value
def delx(self):
print 'delx works...'
del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")
************************************************
>>> c = C()
>>> c.x = 1
setx works...
>>> c.x = 2
setx works...
>>> c.x
getx works...
2
>>> del(c.x)
delx works...
>>> c.y = 1
>>> c.y
1
>>>
вместо любого из аргументов можно передать None тогда данный метод нельзя будет применять.
например:
x = property(getx, setx, None, "I'm the 'x' property.")
...
>>>del(c.x)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: can't delete attribute
Вот неплохая статья:
http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/



Офлайн

#3 Март 18, 2011 01:46:59

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Вопрос по классам (вырезка из книжки)

pill, не следует говорить про __getattr__/__setattr__.
Во первых, это неверно. А во вторых - только запутывает.



Офлайн

#4 Март 18, 2011 02:20:05

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопрос по классам (вырезка из книжки)

Ладно я думаю http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/ можно считать ответом.
А пост - просто доказательством моей частично безграмотности.
Буду больше думать и меньше писать…



Отредактировано (Март 18, 2011 02:21:36)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version