gpt4 book ai didi

python - 有没有一种方法可以禁用定义 __getitem__ 方法的类的迭代而不对键施加约束?

转载 作者:行者123 更新时间:2023-12-01 00:19:11 27 4
gpt4 key购买 nike

作为我的起点的类如下:

class Test:
def __getitem__(self, key):
global frame
frame = inspect.currentframe()
if key > 9:
raise KeyError
return key

我的想法是使用 frame.f_back 来发现为实例自动创建迭代器,如下例所示:

for x in Test():
x

运行这两个程序并查看 frame.f_back 后,不明显 __getitem__ 是否可以获得足够的信息来检测它是否是从任何“迭代器”调用的” 正在与之互动。最简单的解决方案是让容器从 1 而不是从 0 开始来访问其内容,甚至可能在将 key 传递给函数之前强制将其包装在列表中,如下所示:

>>> class Test:
def __getitem__(self, key):
if not isinstance(key, list):
raise TypeError
if len(key) != 1:
raise ValueError
key = key.pop()
if not isinstance(key, int):
raise TypeError
if not 0 <= key < 10:
raise KeyError
return key


>>> for x in Test():
x


Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
for x in Test():
File "<pyshell#39>", line 4, in __getitem__
raise TypeError
TypeError
>>> Test()[[5]]
5
>>>

有没有办法让 __getitem__ 知道它被自动用作迭代器并引发异常以防止这种使用?

相关: Why does defining __getitem__ on a class make it iterable in python?

最佳答案

如果目标是阻止对象成为可迭代对象,您可以在 __iter__ 方法上强制发生错误:

class Test:
def __getitem__(self, key):
if key > 9:
raise KeyError
return key
def __iter__(self):
raise TypeError('Object is not iterable')

测试运行:

>>> t = Test()
>>> for x in t:
print(x)

Traceback (most recent call last):
File "<pyshell#126>", line 1, in <module>
for x in t:
File "<pyshell#122>", line 7, in __iter__
raise TypeError('Object is not iterable')
TypeError: Object is not iterable

但是__getitem__仍然有效:

>>> t[0]
0
>>> t[1]
1
>>> t[10]
Traceback (most recent call last):
File "<pyshell#129>", line 1, in <module>
t[10]
File "<pyshell#122>", line 4, in __getitem__
raise KeyError
KeyError

关于python - 有没有一种方法可以禁用定义 __getitem__ 方法的类的迭代而不对键施加约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59072284/

27 4 0