简体   繁体   English

Python __iter__ 和 __getattr__ 行为

[英]Python __iter__ and __getattr__ behavior

Trying to build something and found this odd behavior.试图构建一些东西并发现这种奇怪的行为。 I'm trying to build a class that I can call dict on我正在尝试构建一个可以调用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 ...}

now in my use case the object has a __getattr__ overload, which is where the problem comes in so现在在我的用例中,object 有一个__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

The dict function is calling somewhere self.keys but obviously Test1().keys throws an AttributeError so it's being handed there somehow. dict function 在某处调用self.keys但显然Test1().keys抛出一个AttributeError所以它以某种方式被交给了那里。 How do I get __iter__ and __getattr__ to play nicely together.我如何让__iter____getattr__一起玩得很好。 Or is there a better way of doing this?或者有没有更好的方法来做到这一点?

Edit:编辑:

I guess raising an AttributeError works我想提高一个 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

You don't actually have to PROVIDE .keys (clearly, or your first example would have failed).您实际上不必提供.keys (显然,否则您的第一个示例将失败)。 You just need to provide the right exception.您只需要提供正确的例外。 This works:这有效:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM