gpt4 book ai didi

python - 使 Python 类在创建新属性时抛出错误

转载 作者:太空宇宙 更新时间:2023-11-03 13:17:16 25 4
gpt4 key购买 nike

假设这是我的类(class):

class A:
def __init__(self):
self.good_attr = None
self.really_good_attr = None
self.another_good_attr = None

然后调用者可以设置这些变量的值:

a = A()
a.good_attr = 'a value'
a.really_good_attr = 'better value'
a.another_good_attr = 'a good value'

但他们也可以添加新的属性:

a.goood_value = 'evil'

这对我的用例来说是不可取的。我的对象被用来将一些值传递给一组方法。 (所以本质上,这个对象替换了一些方法上的一长串共享参数,以避免重复并清楚地区分什么是共享的,什么是不同的。)如果调用者输入了一个属性名称,那么该属性将被忽略,导致意外令人困惑且可能难以弄清楚的行为。最好快速失败,通知调用者他们使用了一个将被忽略的属性名称。因此,当他们使用对象上尚不存在的属性名称时,类似于以下内容的行为是我想要的:

>>> a.goood_value = 'evil'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'goood_value'

我怎样才能做到这一点?

我还想指出,我完全知道调用者可以创建一个新类并做任何他们想做的事,完全绕过这个。但是,这将是不受支持的行为。制作我提供的对象只是创建一个快速失败的愚蠢检查,以节省那些确实利用我提供的对象(包括我自己)的拼写错误的时间,而不是让他们挠头想知道为什么事情会以意想不到的方式表现.

最佳答案

您可以使用 __setattr__ 方法连接到属性设置。此方法为所有 属性设置调用,因此请考虑它也会为您的“正确”属性调用:

class A(object):
good_attr = None
really_good_attr = None
another_good_attr = None

def __setattr__(self, name, value):
if not hasattr(self, name):
raise AttributeError(
'{} instance has no attribute {!r}'.format(
type(self).__name__, name))
super(A, self).__setattr__(name, value)

因为 good_attr 等是在类上定义的,所以 hasattr() 调用会为这些属性返回 True,并且不会引发异常.您也可以在 __init__ 中设置这些相同的属性,但是要在 hasattr() 工作的类上定义这些属性

另一种方法是创建一个您可以测试的白名单。

演示:

>>> a = A()
>>> a.good_attr = 'foo'
>>> a.bad_attr = 'foo'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 10, in __setattr__
AttributeError: A instance has no attribute 'bad_attr'

当然,坚定的开发人员仍然可以通过向 a.__dict__ 实例字典添加键来向您的实例添加属性。

另一种选择是利用 __slots__ 的副作用;插槽用于节省内存,因为字典比将值直接放入 Python 为每个实例创建的 C 结构中占用更多空间(那时不需要键和动态表)。副作用是在这样的类实例上没有更多属性的地方:

class A(object):
__slots__ = ('good_attr', 'really_good_attr', 'another_good_attr')

def __init__(self):
self.good_attr = None
self.really_good_attr = None
self.another_good_attr = None

错误信息如下所示:

>>> a = A()
>>> a.good_attr = 'foo'
>>> a.bad_attr = 'foo'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'bad_attr'

但请务必阅读文档中列出的有关使用 __slots__ 的注意事项。

因为在使用 __slots__ 时没有 __dict__ 实例属性,这个选项实际上关闭了在实例上设置任意属性的大门。

关于python - 使 Python 类在创建新属性时抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25061792/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com