E-rich
E-rich

Reputation: 9511

Setting Property via a String

I'm trying to set a Python class property outside of the class via the setattr(self, item, value) function.

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 )

And in another script, I create an instance and want to specify the property and let the property mutator handle the simple validation.

myClass = MyClass()
new_value = None

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

The problem is that it doesn't appear to be calling the setMyProperty(self, value) mutator. For a quick test to verify that it doesn't get called, I change the mutator to:

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

I'm fairly new to Python, and perhaps there's another way to do what I'm trying to do, but can someone explain why the mutator isn't being called when setattr(self, item, value) is called?

Is there another way to set a property via a string? I need the validation inside the mutator to be executed when setting the property value.

Upvotes: 1

Views: 1167

Answers (1)

Claudiu
Claudiu

Reputation: 229391

Works for me:

>>> 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

The code you pasted seems to do the same as mine, except that my class inherits from object, but that's cause I'm running Python 2.6 and I thought that in 2.7 all classes automatically inherit from object. Try that, though, and see if it helps.

To make it even clearer: try just doing myClass.my_property = 4. Does that raise an exception? If not then it's an issue with inheriting from object - properties only work for new-style classes, i.e. classes that inherit from object.

Upvotes: 4

Related Questions