【问题标题】:Set a custom object attribute设置自定义对象属性
【发布时间】:2025-12-27 15:20:19
【问题描述】:

我在处理继承的类,想知道是否可以使用方法设置自定义对象属性。 它会像这样工作:

class MyClass(object):
    def __init__(self):
        super.__init__()
    def setCustAttr(self, name, value):
        #...
g=MyClass()
g.setCustAttr("var",5)
g.var+=6
g.var="text"
  • 有没有办法做到这一点?
  • 你能用exec("self."+string+"="+value)吗?

【问题讨论】:

  • 不是那个问题的骗子。这个问题是关于setattrobjects 上的失败。这可能是其他东西的欺骗。
  • 我假设你的意思是除了g.var = 5?

标签: python class python-3.x


【解决方案1】:

这就是setattr 函数的作用:

setattr(g, 'var', 5)
# g.var is now 5

【讨论】:

    【解决方案2】:

    传递给setCustAttr 的参数正是您将传递给setattr 的参数。

    def setCustAttr(self, name, value):
        setattr(self, name, value)
    

    为什么要对setattr 进行包装?您可以尝试执行一些验证:

    def setCustAttr(self, name, value):
        if name not in ['bar', 'baz']:
            raise ValueError("Custom attribute must be 'bar' or 'baz'")
        if name == 'bar' and value < 0:
            raise ValueError("'bar' attribute must be non-negative")
        if name == 'baz' and value % 2:
            raise ValueError("'baz' attribute must be even")
    
        setattr(self, name, value)
    

    但是,这并不妨碍您的类的用户忽略您的 setCustAttr 方法并直接分配给对象:

    g = MyClass()
    g.bar = -5  # Negative bar!
    g.baz = 3   # Odd baz!
    g.quux = 2  # Non-bar/baz attribute!
    

    Python 具有强大的魔力,可以更好地控制对象的属性设置方式(参见__slots____{get,set}attr____getattribute__、属性等),但通常它们不仅仅用于防止如上所示的示例。 Python 的方式是只记录应该如何使用您的类的实例,并相信用户会遵守您的指示。 (如果他们不这样做,买者警告。)

    【讨论】:

    • 那么就不需要其他方法了吗?
    • 并非如此。您可以使用这样的包装器来提供验证。 g.setCustAttr("var", 5) 可能首先检查该值是否大于 0(如果不是,则引发 ValueError),或者第一个参数来自一组受限制的名称(模拟 __slots__ 属性的部分功能)。但是,您班级的用户仍然可以忽略您的方法并写g.var = 5
    • 因此您将在设置之前评估新值。谢谢!