【发布时间】:2022-01-02 18:01:50
【问题描述】:
编辑 2:我终于能够制作出 MWE:
from typing import Generic, TypeVar
T = TypeVar('T')
class Cache:
__dict = {}
@classmethod
def add(cls, item):
cls.__dict[item] = (item, [item, item, item, {item: item}])
print('On setting:', item in cls.__dict)
def __init_subclass__(cls, **kwargs):
Cache.add(cls)
class Class(Cache, Generic[T]):
pass
d = Cache._Cache__dict
tp = list(d)[0]
print('On checking:', tp in d)
在 python 3.6 中,输出为:
On setting: True
On checking: False
在 3.8 中是:
On setting: True
On checking: True
如果这还不够好奇,如果我从Generic[T] 中删除继承,那么一切正常。
原创
我正在使用 Python 3.6,当我尝试从字典中获取密钥时得到 KeyError:
# d: Dict[type, Any]
tp = list(d.keys())[0]
d[tp]
# KeyError: ...
意思是从字典中取出的键会导致这个异常。请注意,d 只有一个条目。 key-type 是一个以GenericMeta 作为元类的类型对象,所以这可能是问题所在吗?
我使用调试器验证了以下属性:
-
id(tp)多次调用都一样。 -
hash(tp)多次调用都一样。 tp is list(d.keys())[0]tp == list(d.keys())[0]len(d) == 1
编辑:
print(type(tp)) # <class 'typing.GenericMeta'>print(type(tp)) # <class 'dict'>
我的问题是:这种行为的原因可能是什么?
由于某些包的兼容性问题,我无法更新python版本,所以请不要告诉我更新,除非它是一个已知的错误,在以后的版本中得到解决。
【问题讨论】:
-
请显示一个实际的minimal reproducible example。我不知道你的代码实际上在做什么,所以在我这样做之前,我不得不关闭你的问题,因为它不可重现
-
停止提供可能发生的事情的提示。显示一个我们可以重新创建的实际
dict定义,d[list(d.keys())[0]]会为其引发KeyError。 -
是的,你可以。从真正的字典开始。删除一个键并检查它是否仍然产生错误。如果是,请移除另一个密钥。如果不是,你刚刚删除的key就是问题所在,你可以识别出来。
-
可在 Python 3.6 中重现,而不是在 Python 3.7 中;我的猜测是这是一个已修复的错误。那个错误可能是什么是一个谜。我可以确认
cls.__dict is Cache._Cache__dict即使在 Python 3.6 中也是如此。 -
制作 mcve 做得很好!这从看似无稽之谈变成了有趣的历史蟒蛇奥秘
标签: python dictionary python-3.6