因此,我正在浏览copy
库的源代码,发现了这一点:
cls = type(x)
copier = _copy_dispatch.get(cls)
if copier:
return copier(x)
try:
issc = issubclass(cls, type)
except TypeError: # cls is not a class
issc = False
重要的行是cls = type(x)
和except TypeError: # cls is not a class
。 (以防万一,我在中间留了一行)。 except
子句使我相信,对于某些x
,type(x)
不会返回类,但是我想不出这样的示例。 (我尝试在该子句中添加print
语句,看看是否可以将其触发都没有用)。您能举一个type()
不返回类的示例吗?
答案 0 :(得分:9)
如果您要查询copy.copy
中的支票,则实际上没有必要。这是一个长期存在的错误,但是却是一个琐碎不重要的错误,多年来一直没人愿意修复。但是,碰巧的是,它是fixed just 11 days ago的一部分,是issue 11572的一部分,该错误是一个伞形错误,旨在完成3.8的copy.py
模块的代码覆盖。
这里的根本原因可以回溯到Python 2.2中存在的一个实际问题,直到2.x分支中的某个位置以后(我猜到2.5,包括端点在内,但这只是一个猜测),但未添加此修复程序直到3.4,问题才不复存在。
此检查在Python 2.x中不存在。正如user2357112所追查的那样,它是作为Python 3.4中issue 11480修复程序的一部分添加的。自定义元类的类上的copy.copy
已损坏,并且有必要进行修复,该修复是从copy.deepcopy
复制而来的,但其中包括不再需要的更改。后来从deepcopy
中删除了,但一直停留在copy
中,直到本月。
由三元组发现,原始错误是#502085。
事实上,在2.2版本中,issubclass(type(x), type)
提出TypeError
不仅是可能的,而且实际上是在野外发生的。
在Python 2.1和更早版本中(在PEP 252之前,扩展类型基本上可以将他们想要的内容粘贴在其类型槽中。在2.2+版本中,这会破坏isinstance
和issubclass
。做出一个TypeError
而不是段错误的做法,这已经足够好了,因为谁会在类型槽中插入非类型的字,对吗?好吧,boost::python
的原始版本确实做到了为你。
下一个版本并没有引起这个问题,大概不是每个人都立即升级了(它需要重写部分代码,它不能生成与Python 2.1兼容的模块以及2MB的下载,是吗? “是在224Kbps的双ISDN上还是其他?”,所以一段时间以来,这些异常确实是一件令人担心的事情。
(这仅与旧样式类和新样式类有切线关系,即使在那之前,扩展类型实际上始终都是“新样式”,我很确定要检查其类型是否为类型是在3.0之前添加的。)
从技术上讲,在Python文档中,class
一词含糊不清。有时class
是通过执行class
语句或调用type
构造函数(或调用type
的子类)而创建的。有时class
是type
的实例或type
的子类,在这种情况下,内置类型是类。
根据先前的定义,x = 1
是type(x)
不是类的示例。但是根据后一个定义,它就是-显然是issubclass
使用的定义。因此,这几乎是无关紧要的,除非您正在寻找使某人烦恼的陷阱问题。