Установка свойства через строку

Я пытаюсь установить свойство класса Python вне класса с помощью функции setattr(self, item, value).

class MyClass:
    def getMyProperty(self):
        return self.__my_property

    def setMyProperty(self, value):
        if value is None:
            value = ''
        self.__my_property = value

    my_property = property( getMyProperty, setMyProperty )

А в другом скрипте я создаю экземпляр и хочу указать свойство и позволить мутатору свойства выполнить простую проверку.

myClass = MyClass()
new_value = None

# notice the property in quotes
setattr(myClass, 'my_property', new_value)

Проблема в том, что он не вызывает мутатор setMyProperty(self, value). Для быстрого теста, чтобы убедиться, что он не вызывается, я меняю мутатор на:

    def setMyProperty(self, value):
        raise ValueError('WTF! Why are you not being called?')
        if value is None:
            value = ''
        self.__my_property = value

Я новичок в Python, и, возможно, есть другой способ сделать то, что я пытаюсь сделать, но может ли кто-нибудь объяснить, почему мутатор не вызывается, когда setattr(self, item, value) называется?

Есть ли другой способ установить свойство через строку? Мне нужно, чтобы проверка внутри мутатора выполнялась при установке значения свойства.


person E-rich    schedule 12.03.2011    source источник
comment
Вы действительно определяете свойство, используя свои функции установки и получения? В вашем коде нет такого определения. Как Python должен знать, какой геттер и сеттер использовать для my_property?   -  person Sven Marnach    schedule 13.03.2011
comment
@Sven Marnach: Ой, забыл добавить это в пример. Но да, я определяю это в реальном коде.   -  person E-rich    schedule 13.03.2011


Ответы (1)


Работает на меня:

>>> class MyClass(object):
...   def get(self): return 10
...   def setprop(self, val): raise ValueError("hax%s"%str(val))
...   prop = property(get, setprop)
...
>>> i = MyClass()
>>> i.prop =4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in setprop
ValueError: hax4
>>> i.prop
10
>>> setattr(i, 'prop', 12)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in setprop
ValueError: hax12

Код, который вы вставили, похоже, делает то же самое, что и мой, за исключением того, что мой класс наследуется от object, но это потому, что я использую Python 2.6, и я думал, что в 2.7 все классы автоматически наследуются от object. Однако попробуйте это и посмотрите, поможет ли это.

Чтобы было еще понятнее: попробуйте просто сделать myClass.my_property = 4. Это вызывает исключение? Если нет, то это проблема наследования от object — свойства работают только для классов нового стиля, то есть классов, которые наследуются от object.

person Claudiu    schedule 12.03.2011
comment
Собственно, последний абзац и есть решение: Python 2.7 по-прежнему различает классы старого и нового стиля. - person Sven Marnach; 13.03.2011
comment
Проблема заключалась не в указании того, что он наследуется от object. Спасибо. - person E-rich; 13.03.2011