可以设置Python对象的任何属性
例如,这段代码是Python:
a = object()
a.b = 3
throws AttributeError: 'object' object has no attribute 'b'
但是,这段代码:
class c(object): pass
a = c()
a.b = 3
就可以了。为什么我可以分配属性 b,而类 x 没有该属性?如何使我的类仅定义属性?
For example, this code is Python:
a = object()
a.b = 3
throws AttributeError: 'object' object has no attribute 'b'
But, this piece of code:
class c(object): pass
a = c()
a.b = 3
is just fine. Why can I assign property b, when class x does not have that property? How can I make my classes have only properties defined?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
object
类型是用 C 编写的内置类,不允许您向其添加属性。它已被明确编码以防止这种情况发生。在您自己的类中获得相同行为的最简单方法是使用 __slots__ 属性来定义您想要支持的确切属性的列表。 Python 将只为这些属性保留空间,而不允许任何其他属性。
当然,这种方法有一些注意事项:您无法腌制此类对象,并且期望每个对象都具有
__dict__
属性的代码将会中断。一种“更Pythonic”的方法是使用自定义的__setattr__()
,如另一张海报所示。当然,有很多方法可以解决这个问题,并且没有办法可以设置 __slots__ (除了子类化和将属性添加到子类之外)。一般来说,这并不是您真正想要在 Python 中执行的操作。如果您的类的用户想要在类的实例上存储一些额外的属性,则没有理由不让它们存储,事实上您可能想要这样做的原因有很多。
The
object
type is a built-in class written in C and doesn't let you add attributes to it. It has been expressly coded to prevent it.The easiest way to get the same behavior in your own classes is to use the
__slots__
attribute to define a list of the exact attributes you want to support. Python will reserve space for just those attributes and not allow any others.Of course, there are some caveats with this approach: you can't pickle such objects, and code that expects every object to have a
__dict__
attribute will break. A "more Pythonic" way would be to use a custom__setattr__()
as shown by another poster. Of course there are plenty of ways around that, and no way around setting__slots__
(aside from subclassing and adding your attributes to the subclass).In general, this is not something you should actually want to do in Python. If the user of your class wants to store some extra attributes on instances of the class, there's no reason not to let them, and in fact a lot of reasons why you might want to.
您可以像这样重写
__setattr__
魔术方法的行为。当然,这只会阻止您设置像 ab(点形式)这样的属性。您仍然可以使用
a.__dict__[b]
= value 设置属性。在这种情况下,您也应该重写 __dict__ 方法。You can override the behavior of the
__setattr__
magic method like so.Of course, this will only prevent you from setting attributes like a.b (the dot form). You can still set the attributes using
a.__dict__[b]
= value. In that case, you should override the__dict__
method too.Python 通常允许您在任何对象上设置任何属性。这是一种特殊情况,其中
object
类的行为有所不同。还有一些用 C 实现的模块具有类似的作用。如果您希望您的对象表现得像这样,您可以定义一个
__setattr__(self, name, value)
方法来显式执行raise AttributeError()
code> 如果您尝试设置不在“批准列表”上的成员(请参阅 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/389916)Python generally allows you to set any attribute on any object. This is a special case where the
object
class acts differently. There are also some modules implemented in C that act similarly.If you want your object to behave like this, you can define a
__setattr__(self, name, value)
method that explicitly does araise AttributeError()
if you try to set a member that's not on the "approved list" (see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/389916)创建
object
实例没有任何功能。因此,明确禁用在基本object
类型的实例上设置属性。您必须将其子类化才能创建属性。提示:如果您希望使用一个简单的对象来存储属性,可以通过使用 lambda 创建匿名函数来实现。函数作为对象也能够存储属性,因此这是完全合法的:
Creating an
object
instance has no features. Therefore setting attributes on an instance of a the baseobject
type is expressly disabled. You must subclass it to be able to create attributes.Hint: If you want a simple object to use as something on which to store properties, you can do so by creating an anonymous function with
lambda
. Functions, being objects, are able to store attributes as well, so this is perfectly legit:发生这种情况是因为当您说
ab = 3
时,它会在 a 中创建一个代表 b 的变量。例如,返回 AttributeError: class a has no attribute b
但是此代码
返回 3,因为它将 a 中 b 的值设置为 3。
This happens because when you say
a.b = 3
, it creates a variable in a that represents b. For example,returns
AttributeError: class a has no attribute b
However this code,
returns 3 as it sets the value of b in a, to 3.