可以设置Python对象的任何属性
Python中通常允许您在任何对象上设置任何属性。这是一个特殊情况,其中object
类的行为有所不同。还有一些以C实现的模块也有类似的行为。
如果您希望您的对象表现出这种行为,您可以定义一个__setattr__(self, name, value)
方法,如果您尝试设置一个不在“approved list”上的成员,该方法会显式地执行raise AttributeError()
操作。
解决方法如下:
class YourClass: def __setattr__(self, name, value): if name not in self.approved_list: raise AttributeError() else: super().__setattr__(name, value)
其中,`approved_list`是包含允许设置的属性名称的列表。
您可以参考http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/389916了解更多详细信息。
在Python中,我们可以通过__setattr__
魔法方法来重写对象的属性设置行为。通过在类中定义__setattr__
方法,我们可以控制在设置对象属性时的行为。例如,可以限制对象只能设置特定的属性。
以下是一个示例代码:
class C(object): def __setattr__(self, name, value): allowed_attrs = ('a', 'b', 'c') if name not in allowed_attrs: # raise exception # or do something else pass self.__dict__[name] = value
在上述代码中,C
类重写了__setattr__
方法。在这个方法中,我们定义了一个允许的属性列表allowed_attrs
。当尝试设置对象的属性时,我们会检查要设置的属性名是否在允许的属性列表中。如果不在允许的属性列表中,可以选择抛出异常或者执行其他操作。
然而,需要注意的是,上述代码只能阻止使用点形式(如a.b
)设置属性。仍然可以通过a.__dict__[b]
的方式来设置属性。如果想要阻止这种方式的属性设置,还需要重写__dict__
方法。
通过重写__setattr__
方法,我们可以自定义对象属性设置的行为,并可以限制对象只能设置特定的属性。如果需要阻止使用a.__dict__[b]
的方式设置属性,还需要重写__dict__
方法。
以上就是关于在Python中任意设置对象属性的问题的原因和解决方法的介绍。
Python中的object
类型是一个内置的C类,不允许添加属性。它明确编码以防止这种情况发生。
在自己的类中获得相同的行为最简单的方法是使用__slots__
属性来定义一个你想要支持的属性列表。Python只会为这些属性保留空间,不允许任何其他属性。
class c(object): __slots__ = "foo", "bar", "baz" a = c() a.foo = 3 # 正常运行 a.b = 3 # 报错:AttributeError
当然,这种方法有一些注意事项:你不能pickle这样的对象,而且那些期望每个对象都有一个__dict__
属性的代码将会出错。一个“更Pythonic”的方法是使用自定义的__setattr__()
,正如另一位用户所示。当然,有很多绕过这个问题的方法,但没有绕过设置__slots__
的方法(除非通过子类化并将属性添加到子类中)。
在Python中你实际上不应该这样做。如果你的类的用户想要在类的实例上存储一些额外的属性,没有理由不允许他们这样做,实际上有很多原因为什么你可能希望这样做。
这很棒,我不知道__slots__
。
有趣的方法!我之前不知道__slots__
。然而,我在研究这种方法的注意事项时偶然发现了stackoverflow.com/questions/472000。那个帖子中提到了一些很好的警告。特别是如果我们使用__slots__
,就没有__dict__
方法!
是的,这些是很好的注意事项。一个更Pythonic的方法可能是编写自己的__setattr__()
以禁止非批准的属性。当然,使用__slots__
会节省内存并提高速度。
对坑点进行了编辑。