Найти - Пользователи
Полная версия: Еще про стиль написания программ.
Начало » Python для экспертов » Еще про стиль написания программ.
1 2 3
Александр Кошелев
vigorouz
перекрытие самого свойства решает проблему
Неа. Саму проблему это не решает, а лишь востанавливает поведение.
Александр Кошелев
Ferroman
Да, абсолютно правильно, исправил.
Только у автора вопроса одно подчеркивание изначально:)
ice
Да, я просто с примеров нокиевских брал некоторые моменты. там одно подчеркивание.
Ferroman
неприятный момент при наследовании
Да, есть такое, весьма неприятно, если не знать о такой “особенности”. Может в 3000 будет логичнее этот момент.
cybergrind
а почему это нелогично? вроде все логично. property - объект который инициализируется при создании __класса__, а не при создании объекта.
вынести проперти в метакласс?

а по поводу первого вопроса, я думаю что, не стоит сильно лазить по чужим аттрибутам - нехорошо, для общения с другими классами - есть интерфейсы. если написать один геттер, сеттер - то ничего страшного тут еще нету, а если их становится целая куча - стоит подумать над тем - нахера нужен такой класс? ну это, конечно в простом случае ООП… но если еще строить архитектуру на таком - то можно задуматься над тем - а действительно ли оно надо?
Ferroman
Не логично то, что 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()
Обратите внимание на цену перегрузки: функции getter-setter приходится искать каждый раз. Объект prop один-единственный для всей иерархии, A и B его разделяют. Поэтому работает чуть медленней стандартного.
Ferroman
Отличный пример мощности языка :)
Просто хотелось бы что бы такой “сахар” работал сразу так, как ожидается.
Хоть я property не часто использую - но все равно очень интересно способ выводить такую бородавку :)
ice
а если вообще делать через __getattr__/__setattr__? то есть заводить словарь внутри класса и проверять куда обращаются? это долго будет по времени? особенно если обращений к классу много.

вот тут у нокии есть классы, если я пытаюсь что-то изменить, что менять нельзя, у меня возникает ексепшн “рид онли фиелд”, а те, которые можно менять оно меняет и сразу меняет поведение объекта (вызывается функция-коллбэк моя), как это сделано? кроме вышеозначенных setattr и getattr есть способы?

идия с динамик проперти не плохо, но когда полей не много.

хм … может правда завести словарь. тогда потом проще будет добавлять новые свойства.
shiza
так он и так словарь =)
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