Python的iter和getattr行为

Python的iter和getattr行为,python,dictionary,iterable,Python,Dictionary,Iterable,试图建立一些东西,却发现了这种奇怪的行为。我正在尝试建立一个可以调用dict的类 现在在我的用例中,对象有一个u_getattr_u___)重载,这就是问题所在 class Test2: def __iter__(self): return iter([(a, a) for a in range(10)]) def __getattr__(self, attr): raise Exception(f"why are you callin

试图建立一些东西,却发现了这种奇怪的行为。我正在尝试建立一个可以调用dict的类

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

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,因此不知何故它被传递到了那里。我怎样才能让伊特和盖特在一起踢得很好呢。还是有更好的方法

编辑:

我想提出一个属性错误是有效的

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

您实际上不必提供。密钥,否则您的第一个示例将失败。您只需要提供正确的异常。这项工作:

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

您实际上不必提供。密钥,否则您的第一个示例将失败。您只需要提供正确的异常。这项工作:

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

__getattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这不是胡闹,这正是正确的解决方案。如果您需要提供一些自定义属性,但不想提供键,则可以这样做。请注意,您在此处使用的dicterable、**kwarg是尝试dictmapping后的回退,**kwarg。如果你想满足映射协议,那么你应该考虑实现一个密钥方法和一个GyTimeType,这是更直接的方法。这不是胡闹,这正是正确的解决方案。如果您需要提供一些自定义属性,但不想提供键,则可以这样做。请注意,您在此处使用的dicterable、**kwarg是尝试dictmapping后的回退,**kwarg。如果你想满足映射协议,那么你应该考虑实现一个KEY方法和一个GyTimeType,这是更直接的方法。