我有一个类,其中__getattr__的实现方式很简单,如下所示:

    def __getattr__(self, item): return self.__dict__[item]

我看到的问题是,许多Python库(例如numpypandas)都试图使用此语句嗅探我的对象是否有名为__array__的内容

hasattr(obj, '__array__`)

但我的目标是向他们抛出一个错误,说不存在这样的属性.

我的困境是:如何让我的类在hasattr中表现良好(返回False),而不是抛出错误,同时,如果任何人想要一个不存在的属性,就抛出一个错误(即,我仍然希望在任何其他情况下抛出该错误).

编辑:按要求复制代码:

class A:
    def __getattr__(self, item): return self.__dict__[item]
a = A()
hasattr(a, "lol")

回溯:

  File "<ipython-input-31-b7d3ffac514f>", line 4, in <module>
    hasattr(a, "lol")
  File "<ipython-input-31-b7d3ffac514f>", line 2, in __getattr__
    def __getattr__(self, item): return self.__dict__[item]
KeyError: 'lol'

推荐答案

从文件中:

__getattr__ ... 应该返回属性值或引发AttributeError异常.

hasattr(object, name) ... 通过调用getattr(object, name)并查看它是否引发AttributeError来实现.

所以你只需要筹集AttributeError美元:

class A:
    def __getattr__(self, item):
        try:
            return self.__dict__[item]
        except KeyError:
            classname = type(self).__name__
            msg = f'{classname!r} object has no attribute {item!r}'
            raise AttributeError(msg)

a = A()
print(hasattr(a, "lol"))  # -> False
print(a.lol)  # -> AttributeError: 'A' object has no attribute 'lol'

(此错误消息基于object().lol中的错误消息.)

Python相关问答推荐

单击Python中的复选框后抓取数据

如果我已经使用了time,如何要求Python在12秒后执行另一个操作.sleep

为什么dict(id=1,**{id:2})有时会引发KeyMessage:id而不是TypMessage?

不允许AMBIMA API请求方法

Python -根据另一个数据框中的列编辑和替换数据框中的列值

Pandas :多索引组

通过仅导入pandas来在for循环中进行多情节

计算所有前面行(当前行)中列的值

根据给定日期的状态过滤查询集

Python中使用时区感知日期时间对象进行时间算术的Incredit

如何根据日期和时间将状态更新为已过期或活动?

当多个值具有相同模式时返回空

运行Python脚本时,用作命令行参数的SON文本

查找两极rame中组之间的所有差异

不理解Value错误:在Python中使用迭代对象设置时必须具有相等的len键和值

无法通过python-jira访问jira工作日志(log)中的 comments

修复mypy错误-赋值中的类型不兼容(表达式具有类型xxx,变量具有类型yyy)

如何并行化/加速并行numba代码?

如何在Python中使用另一个数据框更改列值(列表)

处理具有多个独立头的CSV文件