可以设置Python对象的任何属性

8 浏览
0 Comments

可以设置Python对象的任何属性

例如,这段代码是Python的:\n

a = object()
a.b = 3

\n会抛出AttributeError: \'object\' object has no attribute \'b\'异常。\n但是,这段代码:\n

class c(object): pass
a = c()
a.b = 3

\n却没有问题。为什么我能给属性b赋值,而类x并没有定义该属性?我该如何让我的类仅拥有已定义的属性?

0
0 Comments

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了解更多详细信息。

0
0 Comments

在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中任意设置对象属性的问题的原因和解决方法的介绍。

0
0 Comments

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__会节省内存并提高速度。

对坑点进行了编辑。

0