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
尝试构建一些东西并发现了这种奇怪的行为。我正在尝试构建一个可以在
上调用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