Python __iter__ 和 __getattr__ 行为

Python __iter__ and __getattr__ behavior

尝试构建一些东西并发现了这种奇怪的行为。我正在尝试构建一个可以在

上调用 dict 的 class
class Test1:
    def __iter__(self):
        return iter([(a, a) for a in range(10)])

obj = Test1()
dict(obj)  # returns {0: 0, 1: 1, 2: 2 ...}

现在在我的用例中,对象有一个 __getattr__ 重载,这就是问题所在

class Test2:
    def __iter__(self):
        return iter([(a, a) for a in range(10)])

    def __getattr__(self, attr):
        raise Exception(f"why are you calling me {attr}")

obj = Test2()
dict(obj)  # Exception: why are you calling me keys

dict 函数正在某处调用 self.keys 但显然 Test1().keys 抛出一个 AttributeError 所以它以某种方式被传递到那里。如何让 __iter____getattr__ 一起玩得很好。或者有更好的方法吗?

编辑:

我想引发 AttributeError 是可行的

class Test2:
    def __iter__(self):
        return iter([(a, a) for a in range(10)])

    def __getattr__(self, attr):
        raise AttributeError(f"why are you calling me {attr}")

obj = Test2()
dict(obj). # No Exception

您实际上不必提供 .keys(显然,否则您的第一个示例会失败)。您只需要提供正确的异常。这有效:

class Test2:
    def __iter__(self):
        return iter([(a, a) for a in range(10)])

    def __getattr__(self, attr):
        if attr == 'keys':
            raise AttributeError(f"{type(self).__name__!r} object has no attribute {attr!r}")
        raise Exception(f"why are you calling me {attr}")

obj = Test2()
dict(obj)  # Exception: why are you calling me keys