Форум сайта python.su
vigorouzНеа. Саму проблему это не решает, а лишь востанавливает поведение.
перекрытие самого свойства решает проблему
Офлайн
FerromanТолько у автора вопроса одно подчеркивание изначально:)
Да, абсолютно правильно, исправил.
Офлайн
Да, я просто с примеров нокиевских брал некоторые моменты. там одно подчеркивание.
Отредактировано (Окт. 14, 2008 14:34:39)
Офлайн
неприятный момент при наследованииДа, есть такое, весьма неприятно, если не знать о такой “особенности”. Может в 3000 будет логичнее этот момент.
Офлайн
а почему это нелогично? вроде все логично. property - объект который инициализируется при создании __класса__, а не при создании объекта.
вынести проперти в метакласс?
а по поводу первого вопроса, я думаю что, не стоит сильно лазить по чужим аттрибутам - нехорошо, для общения с другими классами - есть интерфейсы. если написать один геттер, сеттер - то ничего страшного тут еще нету, а если их становится целая куча - стоит подумать над тем - нахера нужен такой класс? ну это, конечно в простом случае ООП… но если еще строить архитектуру на таком - то можно задуматься над тем - а действительно ли оно надо?
Отредактировано (Окт. 14, 2008 18:59:38)
Офлайн
Не логично то, что property в примере тянет значение родительского класса, а не дочернего. То есть, для меня, более логичным было бы то, что при наследовании и перегрузке метода генерирующего property дочерним классом родительского метода, пр генерации property использовался бы новый метод, а не метод родителя.
Вот так:
class A(object):
def _get_name(self):
return 'A'
name = property(_get_name)
class B(A):
def _get_name(self): # перегружаем метод родительского класса
return 'B'
In: a.name
Out: 'A'
In: b.name
Out: 'В'
Офлайн
Легко сделать свою реализацию. Все помнят, что property - всего лишь пример тривиальнейшего дескриптора?
Хотя бы такую (внимание, набор юнит-тестов, естественно, далеко не полон, да и что ожидать от трехминутной работы…)
class dynamic_property(object):
'''property with lazy method binding'''
def __init__(self, getter, setter=None, deleter=None, doc=None):
self._getter_name = getter.__name__
self._setter_name = setter.__name__ if setter is not None else None
self._deleter_name = deleter.__name__ if deleter is not None else None
self.__doc__ = doc
def __get__(self, instance, owner):
assert instance is not None #like standard property
getter = getattr(owner, self._getter_name)
return getter(instance)
def __set__(self, instance, value):
setter = getattr(instance.__class__, self._setter_name)
return setter(instance, value)
def __delete__(self, instance):
deleter = getattr(instance.__class__, self._deleter_name)
return deleter(instance)
import unittest
class A(object):
val = None
def _get(self):
return 'A._get_'+str(self.val)
def _set(self, val):
self.val = val
def _del(self):
self.val = 'deleted'
prop = dynamic_property(_get, _set, _del, 'doc-string')
class B(A):
def _get(self):
return 'B._get_'+str(self.val)
class Test_dynamic_property(unittest.TestCase):
def setUp(self):
self.a = A()
def test_get(self):
self.assertEqual('A._get_None', self.a.prop)
self.a.val = 'val'
self.assertEqual('A._get_val', self.a.prop)
def test_set(self):
self.assertEqual('A._get_None', self.a.prop)
self.a.prop = 'val'
self.assertEqual('A._get_val', self.a.prop)
def test_set(self):
self.assertEqual('A._get_None', self.a.prop)
self.a.prop = 'val'
self.assertEqual('A._get_val', self.a.prop)
def test_del(self):
self.a.prop = 'val'
self.assertEqual('A._get_val', self.a.prop)
del self.a.prop
self.assertEqual('deleted', self.a.val)
def test_overload(self):
b = B()
self.assertEqual('B._get_None', b.prop)
b.val = 'val'
self.assertEqual('B._get_val', b.prop)
if __name__ == '__main__':
unittest.main()
Отредактировано (Окт. 14, 2008 22:12:45)
Офлайн
Отличный пример мощности языка :)
Просто хотелось бы что бы такой “сахар” работал сразу так, как ожидается.
Хоть я property не часто использую - но все равно очень интересно способ выводить такую бородавку :)
Офлайн
а если вообще делать через __getattr__/__setattr__? то есть заводить словарь внутри класса и проверять куда обращаются? это долго будет по времени? особенно если обращений к классу много.
вот тут у нокии есть классы, если я пытаюсь что-то изменить, что менять нельзя, у меня возникает ексепшн “рид онли фиелд”, а те, которые можно менять оно меняет и сразу меняет поведение объекта (вызывается функция-коллбэк моя), как это сделано? кроме вышеозначенных setattr и getattr есть способы?
идия с динамик проперти не плохо, но когда полей не много.
хм … может правда завести словарь. тогда потом проще будет добавлять новые свойства.
Офлайн
так он и так словарь =)
Офлайн