通过字符串设置属性

1 投票
1 回答
1148 浏览
提问于 2025-04-16 13:34

我正在尝试通过setattr(self, item, value)这个函数在类外部设置一个Python类的属性。

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)时没有调用修改器吗?

有没有其他方法可以通过字符串来设置属性?我需要在设置属性值时执行修改器中的验证。

1 个回答

4

对我来说是有效的:

>>> 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 继承的类。

撰写回答